FIR: Refine inference constraints when type variable in flexible position

That issue might be fixed via changing
TypeVariableMarker.shouldBeFlexible at ConeConstraintSystemUtilContext
but this and some other tricks have been added because of incorrect
handling of constraints where type variable has a flexible bound

^KT-51168 Fixed
This commit is contained in:
Denis.Zharkov
2022-04-12 16:30:55 +03:00
committed by teamcity
parent 853b7ec078
commit f70ae2df3a
54 changed files with 411 additions and 154 deletions
@@ -15,7 +15,6 @@ import org.jetbrains.kotlin.fir.resolve.inference.model.ConeExplicitTypeParamete
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap
import org.jetbrains.kotlin.fir.scopes.impl.toConeType
import org.jetbrains.kotlin.fir.symbols.ConeTypeParameterLookupTag
import org.jetbrains.kotlin.fir.symbols.ensureResolved
import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.name.StandardClassIds
@@ -66,11 +65,7 @@ internal object CreateFreshTypeVariableSubstitutorStage : ResolutionStage() {
when (val typeArgument = candidate.typeArgumentMapping[index]) {
is FirTypeProjectionWithVariance -> csBuilder.addEqualityConstraint(
freshVariable.defaultType,
getTypePreservingFlexibilityWrtTypeVariable(
typeArgument.typeRef.coneType,
typeParameter,
context.session
).fullyExpandedType(context.session),
typeArgument.typeRef.coneType.fullyExpandedType(context.session),
ConeExplicitTypeParameterConstraintPosition(typeArgument)
)
is FirStarProjection -> csBuilder.addEqualityConstraint(
@@ -85,29 +80,6 @@ internal object CreateFreshTypeVariableSubstitutorStage : ResolutionStage() {
}
}
}
private fun getTypePreservingFlexibilityWrtTypeVariable(
type: ConeKotlinType,
typeParameter: FirTypeParameterRef,
session: FirSession,
): ConeKotlinType {
return if (typeParameter.shouldBeFlexible(session.typeContext)) {
val notNullType = type.withNullability(ConeNullability.NOT_NULL, session.typeContext) as ConeSimpleKotlinType
ConeFlexibleType(notNullType, notNullType.withNullability(ConeNullability.NULLABLE, session.typeContext))
} else {
type
}
}
private fun FirTypeParameterRef.shouldBeFlexible(context: ConeTypeContext): Boolean {
return symbol.resolvedBounds.any {
val type = it.coneType
type is ConeFlexibleType || with(context) {
(type.typeConstructor() as? ConeTypeParameterLookupTag)?.symbol?.fir?.shouldBeFlexible(context) ?: false
}
}
}
}
private fun createToFreshVariableSubstitutorAndAddInitialConstraints(
@@ -21,7 +21,8 @@ import org.jetbrains.kotlin.types.model.TypeVariableMarker
object ConeConstraintSystemUtilContext : ConstraintSystemUtilContext {
override fun TypeVariableMarker.shouldBeFlexible(): Boolean {
// TODO
// In FIR, there's no need in hack with shouldTryUseDifferentFlexibilityForUpperType
// See org.jetbrains.kotlin.types.model.TypeSystemInferenceExtensionContext.useRefinedBoundsForTypeVariableInFlexiblePosition
return false
}