FIR: implement FE1.0-matching ILT approximation during inference
#KT-51357 Fixed
This commit is contained in:
+3
-1
@@ -20,7 +20,9 @@ import org.jetbrains.kotlin.types.model.typeConstructor
|
||||
|
||||
internal fun ConeKotlinType.substitutedUnderlyingTypeForInlineClass(session: FirSession, context: ConeTypeContext): ConeKotlinType? {
|
||||
val unsubstitutedType = unsubstitutedUnderlyingTypeForInlineClass(session) ?: return null
|
||||
val substitutor = createTypeSubstitutorByTypeConstructor(mapOf(this.typeConstructor(context) to this), context)
|
||||
val substitutor = createTypeSubstitutorByTypeConstructor(
|
||||
mapOf(this.typeConstructor(context) to this), context, approximateIntegerLiterals = true
|
||||
)
|
||||
return substitutor.substituteOrNull(unsubstitutedType)
|
||||
}
|
||||
|
||||
|
||||
+7
-2
@@ -217,13 +217,18 @@ class ConeSubstitutorByMap(
|
||||
override fun hashCode() = hashCode
|
||||
}
|
||||
|
||||
fun createTypeSubstitutorByTypeConstructor(map: Map<TypeConstructorMarker, ConeKotlinType>, context: ConeTypeContext): ConeSubstitutor {
|
||||
fun createTypeSubstitutorByTypeConstructor(
|
||||
map: Map<TypeConstructorMarker, ConeKotlinType>,
|
||||
context: ConeTypeContext,
|
||||
approximateIntegerLiterals: Boolean
|
||||
): ConeSubstitutor {
|
||||
if (map.isEmpty()) return ConeSubstitutor.Empty
|
||||
return object : AbstractConeSubstitutor(context), TypeSubstitutorMarker {
|
||||
override fun substituteType(type: ConeKotlinType): ConeKotlinType? {
|
||||
if (type !is ConeLookupTagBasedType && type !is ConeStubType) return null
|
||||
val new = map[type.typeConstructor(context)] ?: return null
|
||||
return new.approximateIntegerLiteralType().updateNullabilityIfNeeded(type)?.withCombinedAttributesFrom(type)
|
||||
val approximatedIntegerLiteralType = if (approximateIntegerLiterals) new.approximateIntegerLiteralType() else new
|
||||
return approximatedIntegerLiteralType.updateNullabilityIfNeeded(type)?.withCombinedAttributesFrom(type)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -329,7 +329,9 @@ interface ConeInferenceContext : TypeSystemInferenceExtensionContext, ConeTypeCo
|
||||
|
||||
override fun typeSubstitutorByTypeConstructor(map: Map<TypeConstructorMarker, KotlinTypeMarker>): ConeSubstitutor {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
return createTypeSubstitutorByTypeConstructor(map as Map<TypeConstructorMarker, ConeKotlinType>, this)
|
||||
return createTypeSubstitutorByTypeConstructor(
|
||||
map as Map<TypeConstructorMarker, ConeKotlinType>, this, approximateIntegerLiterals = false
|
||||
)
|
||||
}
|
||||
|
||||
override fun createEmptySubstitutor(): ConeSubstitutor {
|
||||
|
||||
@@ -128,6 +128,7 @@ fun <T : ConeKotlinType> T.withAttributes(attributes: ConeAttributes): T {
|
||||
is ConeIntersectionType -> this
|
||||
// Attributes for stub types are not supported, and it's not obvious if it should
|
||||
is ConeStubType -> this
|
||||
is ConeIntegerLiteralType -> this
|
||||
else -> error("Not supported: $this: ${this.render()}")
|
||||
} as T
|
||||
}
|
||||
|
||||
+1
-1
@@ -453,7 +453,7 @@ class FirCallCompletionResultsWriterTransformer(
|
||||
|
||||
private fun Candidate.createArgumentsMapping(): ExpectedArgumentType? {
|
||||
val lambdasReturnType = postponedAtoms.filterIsInstance<ResolvedLambdaAtom>().associate {
|
||||
Pair(it.atom, finalSubstitutor.substituteOrSelf(substitutor.substituteOrSelf(it.returnType)))
|
||||
Pair(it.atom, finalSubstitutor.substituteOrSelf(substitutor.substituteOrSelf(it.returnType)).approximateIntegerLiteralType())
|
||||
}
|
||||
|
||||
val isIntegerOperator = symbol.isWrappedIntegerOperator()
|
||||
|
||||
+6
-2
@@ -318,7 +318,9 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor
|
||||
}
|
||||
val typeVariableTypeToStubType = context.inferenceSession.createSyntheticStubTypes(system)
|
||||
|
||||
val substitutor = createTypeSubstitutorByTypeConstructor(typeVariableTypeToStubType, session.typeContext)
|
||||
val substitutor = createTypeSubstitutorByTypeConstructor(
|
||||
typeVariableTypeToStubType, session.typeContext, approximateIntegerLiterals = true
|
||||
)
|
||||
val delegateExpressionTypeRef = delegateExpression.typeRef
|
||||
val stubTypeSubstituted = substitutor.substituteOrNull(delegateExpressionTypeRef.coneType)
|
||||
delegateExpression.replaceTypeRef(delegateExpressionTypeRef.withReplacedConeType(stubTypeSubstituted))
|
||||
@@ -338,7 +340,9 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor
|
||||
system.markPostponedVariable(it.value.typeVariable)
|
||||
}
|
||||
val typeVariableTypeToStubType = context.inferenceSession.createSyntheticStubTypes(system)
|
||||
val substitutor = createTypeSubstitutorByTypeConstructor(typeVariableTypeToStubType, session.typeContext)
|
||||
val substitutor = createTypeSubstitutorByTypeConstructor(
|
||||
typeVariableTypeToStubType, session.typeContext, approximateIntegerLiterals = true
|
||||
)
|
||||
|
||||
val stubTypeSubstituted = substitutor.substituteOrSelf(provideDelegateCandidate.substitutor.substituteOrSelf(components.typeFromCallee(provideDelegateCall).type))
|
||||
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
class Expression<T>(val x: T)
|
||||
|
||||
class GreaterOp(val expr1: Expression<*>, val expr2: Expression<*>)
|
||||
|
||||
fun <T : Comparable<T>, S : T?> Expression<in S>.greater(other: T): GreaterOp =
|
||||
GreaterOp(this, Expression(other))
|
||||
|
||||
fun foo(countExpr: Expression<Long>) {
|
||||
<!NEW_INFERENCE_ERROR!>countExpr.greater(0)<!>
|
||||
countExpr.greater("0")
|
||||
countExpr.greater<String, Nothing>("0")
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
class Expression<T>(val x: T)
|
||||
|
||||
class GreaterOp(val expr1: Expression<*>, val expr2: Expression<*>)
|
||||
|
||||
Reference in New Issue
Block a user