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
@@ -289,15 +289,19 @@ interface TypeSystemInferenceExtensionContext : TypeSystemContext, TypeSystemBui
}
/**
* For case Foo <: (T..T?) return LowerBound for new constraint LowerBound <: T
* In FE 1.0, in case nullable it was just Foo?, so constraint was Foo? <: T
* For case Foo <: (T..T?) return LowerConstraint for new constraint LowerConstraint <: T
* In K1, in case nullable it was just Foo?, so constraint was Foo? <: T
* But it's not 100% correct because prevent having not-nullable upper constraint on T while initial (Foo? <: (T..T?)) is not violated
*
* In FIR, we try to have a correct one: (Foo!!..Foo?) <: T
* In FIR, we try to have a correct one: (Foo & Any..Foo?) <: T
*
* The same logic applies for T! <: UpperConstraint, as well
* In K1, it was reduced to T <: UpperConstraint..UpperConstraint?
* In FIR, we use UpperConstraint & Any..UpperConstraint?
*
* In future once we have only FIR (or FE 1.0 behavior is fixed) this method should be inlined to the use-site
*/
fun SimpleTypeMarker.createConstraintPartForLowerBoundAndFlexibleTypeVariable(): KotlinTypeMarker
fun useRefinedBoundsForTypeVariableInFlexiblePosition(): Boolean
fun createCapturedStarProjectionForSelfType(
typeVariable: TypeVariableTypeConstructorMarker,
@@ -25,6 +25,7 @@ import org.jetbrains.kotlin.resolve.substitutedUnderlyingType
import org.jetbrains.kotlin.resolve.unsubstitutedUnderlyingType
import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.types.error.ErrorTypeKind
import org.jetbrains.kotlin.types.error.ErrorUtils
import org.jetbrains.kotlin.types.model.*
import org.jetbrains.kotlin.types.typeUtil.*
import org.jetbrains.kotlin.utils.addIfNotNull
@@ -33,7 +34,6 @@ import org.jetbrains.kotlin.utils.addToStdlib.safeAs
import org.jetbrains.kotlin.types.typeUtil.isSignedOrUnsignedNumberType as classicIsSignedOrUnsignedNumberType
import org.jetbrains.kotlin.types.typeUtil.isStubType as isSimpleTypeStubType
import org.jetbrains.kotlin.types.typeUtil.isStubTypeForBuilderInference as isSimpleTypeStubTypeForBuilderInference
import org.jetbrains.kotlin.types.error.ErrorUtils
import org.jetbrains.kotlin.types.typeUtil.isStubTypeForVariableInSubtyping as isSimpleTypeStubTypeForVariableInSubtyping
interface ClassicTypeSystemContext : TypeSystemInferenceExtensionContext, TypeSystemCommonBackendContext {
@@ -876,12 +876,7 @@ interface ClassicTypeSystemContext : TypeSystemInferenceExtensionContext, TypeSy
return (baseType.memberScope as? SubstitutingScope)?.substitutor
}
override fun SimpleTypeMarker.createConstraintPartForLowerBoundAndFlexibleTypeVariable(): KotlinTypeMarker =
if (this.isMarkedNullable()) {
this
} else {
createFlexibleType(this, this.withNullability(true))
}
override fun useRefinedBoundsForTypeVariableInFlexiblePosition(): Boolean = false
override fun substitutionSupertypePolicy(type: SimpleTypeMarker): TypeCheckerState.SupertypesPolicy {
require(type is SimpleType, type::errorMessage)