FIR: implement FE1.0-matching ILT approximation during inference

#KT-51357 Fixed
This commit is contained in:
Mikhail Glukhikh
2022-02-16 15:24:23 +03:00
committed by Space
parent 6506d35aa6
commit 6e53dd1a4b
8 changed files with 22 additions and 19 deletions
@@ -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)
}
@@ -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
}
@@ -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()
@@ -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<*>)