[FIR] Don't approximate captured types

This fixes some type argument mismatch errors caused by a captured type
being approximated and then captured again.
Some places need to be adapted to work with captured types that
previously only worked with approximated types.

#KT-62959 Fixed
This commit is contained in:
Kirill Rakhman
2023-12-20 11:10:25 +01:00
committed by Space Team
parent b6d7f35ebf
commit 251827c9aa
58 changed files with 506 additions and 86 deletions
@@ -416,8 +416,21 @@ class ConstraintSystemCompleter(components: BodyResolveComponents, private val c
variableWithConstraints,
TypeVariableDirectionCalculator.ResolveDirection.UNKNOWN
)
val resultTypeForOnlyInputTypes =
if (with(ConeConstraintSystemUtilContext) { variableWithConstraints.typeVariable.hasOnlyInputTypesAttribute() }) {
inferenceComponents.resultTypeResolver.findResultType(
c,
variableWithConstraints,
TypeVariableDirectionCalculator.ResolveDirection.UNKNOWN,
isForOnlyInputTypes = true
)
} else {
resultType
}
val variable = variableWithConstraints.typeVariable
c.fixVariable(variable, resultType, ConeFixVariableConstraintPosition(variable))
c.fixVariable(variable, resultType, ConeFixVariableConstraintPosition(variable), resultTypeForOnlyInputTypes)
}
companion object {
@@ -389,7 +389,7 @@ class FirCallCompleter(
}
return session.typeApproximator.approximateToSuperType(
this, TypeApproximatorConfiguration.FinalApproximationAfterResolutionAndInference
this, TypeApproximatorConfiguration.IntermediateApproximationToSupertypeAfterCompletionInK2
) ?: this
}
@@ -495,7 +495,8 @@ class FirCallCompletionResultsWriterTransformer(
val initialType = candidate.substitutor.substituteOrSelf(type)
val substitutedType = finallySubstituteOrNull(initialType)
val finalType = typeApproximator.approximateToSuperType(
type = substitutedType ?: initialType, TypeApproximatorConfiguration.FinalApproximationAfterResolutionAndInference,
type = substitutedType ?: initialType,
TypeApproximatorConfiguration.IntermediateApproximationToSupertypeAfterCompletionInK2,
) ?: substitutedType
// This is probably a temporary hack, but it seems necessary because elvis has that attribute and it may leak further like
@@ -968,7 +969,7 @@ class FirCallCompletionResultsWriterTransformer(
arrayLiteral.transformChildren(this, expectedArrayElementType?.toExpectedType())
val arrayElementType =
session.typeContext.commonSuperTypeOrNull(arrayLiteral.arguments.map { it.resolvedType })?.let {
typeApproximator.approximateToSuperType(it, TypeApproximatorConfiguration.FinalApproximationAfterResolutionAndInference)
typeApproximator.approximateToSuperType(it, TypeApproximatorConfiguration.IntermediateApproximationToSupertypeAfterCompletionInK2)
?: it
} ?: expectedArrayElementType ?: session.builtinTypes.nullableAnyType.type
arrayLiteral.resultType =
@@ -33,6 +33,7 @@ import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.visitors.FirTransformer
import org.jetbrains.kotlin.fir.visitors.FirVisitor
import org.jetbrains.kotlin.name.StandardClassIds
import org.jetbrains.kotlin.types.TypeApproximatorConfiguration
class FirWhenExhaustivenessTransformer(private val bodyResolveComponents: BodyResolveComponents) : FirTransformer<Any?>() {
companion object {
@@ -119,7 +120,9 @@ class FirWhenExhaustivenessTransformer(private val bodyResolveComponents: BodyRe
}
val session = bodyResolveComponents.session
val subjectType = getSubjectType(session, whenExpression) ?: run {
val subjectType = getSubjectType(session, whenExpression)?.let {
session.typeApproximator.approximateToSuperType(it, TypeApproximatorConfiguration.FinalApproximationAfterResolutionAndInference) ?: it
} ?: run {
whenExpression.replaceExhaustivenessStatus(ExhaustivenessStatus.NotExhaustive.NO_ELSE_BRANCH)
return
}
@@ -1717,7 +1717,7 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT
)
} else {
session.typeApproximator.approximateToSuperType(
typeFromCallee.type, TypeApproximatorConfiguration.FinalApproximationAfterResolutionAndInference
typeFromCallee.type, TypeApproximatorConfiguration.IntermediateApproximationToSupertypeAfterCompletionInK2
)
} ?: typeFromCallee.type
}
@@ -18,6 +18,7 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol
import org.jetbrains.kotlin.fir.symbols.lazyResolveToPhase
import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.types.AbstractTypeChecker
import org.jetbrains.kotlin.types.TypeApproximatorConfiguration
fun BodyResolveComponents.computeRepresentativeTypeForBareType(type: ConeClassLikeType, originalType: ConeKotlinType): ConeKotlinType? {
originalType.lowerBoundIfFlexible().fullyExpandedType(session).let {
@@ -30,6 +31,13 @@ fun BodyResolveComponents.computeRepresentativeTypeForBareType(type: ConeClassLi
return candidatesFromIntersectedTypes.firstOrNull()
}
session.typeApproximator.approximateToSuperType(
originalType,
TypeApproximatorConfiguration.FinalApproximationAfterResolutionAndInference
)?.let {
return computeRepresentativeTypeForBareType(type, it)
}
val originalClassLookupTag = (originalType as? ConeClassLikeType)?.fullyExpandedType(session)?.lookupTag ?: return null
val castTypeAlias = type.lookupTag.toSymbol(session)?.fir as? FirTypeAlias