FIR: replace constraint with NotFixedTypeToVariableSubstitutor properly
In this commit we add nullability to upper type of a substituted constraint in the situation like (Stub<_L> <: SomeType), where _L is fixed to nullable Stub<_L>?. We have to change this constraint to L <: SomeType? and not to L <: SomeType as before, otherwise nullability become broken (direct substitution of Stub<_L> to L is illegal here). #KT-50470 Fixed
This commit is contained in:
committed by
teamcity
parent
dafc6d849c
commit
6342eb96c0
Vendored
+2
-2
@@ -61,8 +61,8 @@ FILE: expectedType.kt
|
||||
public final val property: R|FirProperty| = R|<local>/property|
|
||||
public get(): R|FirProperty|
|
||||
|
||||
public final val expectedType: R|ConeKotlinType?|by <Inapplicable(INAPPLICABLE): /myLazy>#<R|ConeKotlinType|>(<L> = myLazy@fun <anonymous>(): R|ConeKotlinType| <inline=NoInline> {
|
||||
^ this@R|/Session|.R|/Session.property|.R|/FirProperty.returnTypeRef|.<Inapplicable(INAPPLICABLE): /coneTypeSafe>#<R|ConeKotlinType|>()
|
||||
public final val expectedType: R|ConeKotlinType?|by R|/myLazy|<R|ConeKotlinType?|>(<L> = myLazy@fun <anonymous>(): R|ConeKotlinType?| <inline=NoInline> {
|
||||
^ this@R|/Session|.R|/Session.property|.R|/FirProperty.returnTypeRef|.R|/coneTypeSafe|<R|ConeKotlinType|>()
|
||||
}
|
||||
)
|
||||
public get(): R|ConeKotlinType?| {
|
||||
|
||||
+1
-1
@@ -219,7 +219,7 @@ internal class TypeSubstitutorByTypeConstructor(
|
||||
|
||||
// Note: builder inference uses TypeSubstitutorByTypeConstructor for not fixed type substitution
|
||||
class NotFixedTypeToVariableSubstitutorForDelegateInference(
|
||||
private val bindings: Map<TypeVariableMarker, ConeKotlinType>,
|
||||
val bindings: Map<TypeVariableMarker, ConeKotlinType>,
|
||||
typeContext: ConeTypeContext
|
||||
) : AbstractConeSubstitutor(typeContext) {
|
||||
override fun substituteType(type: ConeKotlinType): ConeKotlinType? {
|
||||
|
||||
+32
-5
@@ -13,14 +13,12 @@ import org.jetbrains.kotlin.fir.resolve.calls.ResolutionContext
|
||||
import org.jetbrains.kotlin.fir.resolve.calls.candidate
|
||||
import org.jetbrains.kotlin.fir.resolve.inference.model.ConeBuilderInferenceSubstitutionConstraintPosition
|
||||
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.components.ConstraintSystemCompletionContext
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintKind
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.model.InitialConstraint
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.model.NewConstraintSystemImpl
|
||||
import org.jetbrains.kotlin.types.model.StubTypeMarker
|
||||
import org.jetbrains.kotlin.types.model.TypeSubstitutorMarker
|
||||
import org.jetbrains.kotlin.types.model.TypeVariableMarker
|
||||
import org.jetbrains.kotlin.types.model.safeSubstitute
|
||||
import org.jetbrains.kotlin.types.model.*
|
||||
|
||||
abstract class AbstractManyCandidatesInferenceSession(
|
||||
protected val resolutionContext: ResolutionContext
|
||||
@@ -60,8 +58,10 @@ abstract class AbstractManyCandidatesInferenceSession(
|
||||
initialConstraint: InitialConstraint,
|
||||
callSubstitutor: ConeSubstitutor,
|
||||
nonFixedToVariablesSubstitutor: ConeSubstitutor,
|
||||
fixedTypeVariables: Map<TypeConstructorMarker, KotlinTypeMarker>,
|
||||
): Boolean {
|
||||
val substitutedConstraintWith = initialConstraint.substitute(callSubstitutor).substitute(nonFixedToVariablesSubstitutor)
|
||||
val substitutedConstraintWith =
|
||||
initialConstraint.substitute(callSubstitutor).substitute(nonFixedToVariablesSubstitutor, fixedTypeVariables)
|
||||
val lower = substitutedConstraintWith.a // TODO: SUB
|
||||
val upper = substitutedConstraintWith.b // TODO: SUB
|
||||
|
||||
@@ -95,4 +95,31 @@ abstract class AbstractManyCandidatesInferenceSession(
|
||||
ConeBuilderInferenceSubstitutionConstraintPosition(this) // TODO
|
||||
)
|
||||
}
|
||||
|
||||
protected fun InitialConstraint.substitute(
|
||||
substitutor: TypeSubstitutorMarker,
|
||||
fixedTypeVariables: Map<TypeConstructorMarker, KotlinTypeMarker>
|
||||
): InitialConstraint {
|
||||
val substituted = substitute(substitutor)
|
||||
val a = a
|
||||
// In situation when some type variable _T is fixed to Stub(_T)?,
|
||||
// we are not allowed just to substitute Stub(_T) with T because nullabilities are different here!
|
||||
// To compensate this, we have to substitute Stub(_T) <: SomeType constraint with T <: SomeType? adding nullability to upper type
|
||||
if (a is ConeStubTypeForChainInference && substituted.a !is ConeStubTypeForChainInference) {
|
||||
val constructor = a.constructor
|
||||
val fixedTypeVariableType = fixedTypeVariables[constructor.variable.typeConstructor]
|
||||
if (fixedTypeVariableType is ConeStubTypeForChainInference &&
|
||||
fixedTypeVariableType.constructor === constructor &&
|
||||
fixedTypeVariableType.isMarkedNullable
|
||||
) {
|
||||
return InitialConstraint(
|
||||
substituted.a,
|
||||
(substituted.b as ConeKotlinType).withNullability(ConeNullability.NULLABLE, resolutionContext.typeContext),
|
||||
substituted.constraintKind,
|
||||
substituted.position
|
||||
)
|
||||
}
|
||||
}
|
||||
return substituted
|
||||
}
|
||||
}
|
||||
|
||||
+4
-1
@@ -197,7 +197,10 @@ class FirBuilderInferenceSession(
|
||||
|
||||
for (initialConstraint in storage.initialConstraints) {
|
||||
if (initialConstraint.position is BuilderInferencePosition) continue
|
||||
if (integrateConstraintToSystem(commonSystem, initialConstraint, callSubstitutor, nonFixedToVariablesSubstitutor)) {
|
||||
if (integrateConstraintToSystem(
|
||||
commonSystem, initialConstraint, callSubstitutor, nonFixedToVariablesSubstitutor, storage.fixedTypeVariables
|
||||
)
|
||||
) {
|
||||
introducedConstraint = true
|
||||
}
|
||||
}
|
||||
|
||||
+4
-1
@@ -300,7 +300,10 @@ class FirDelegatedPropertyInferenceSession(
|
||||
var introducedConstraint = false
|
||||
|
||||
for (initialConstraint in storage.initialConstraints) {
|
||||
if (integrateConstraintToSystem(commonSystem, initialConstraint, callSubstitutor, nonFixedToVariablesSubstitutor)) {
|
||||
if (integrateConstraintToSystem(
|
||||
commonSystem, initialConstraint, callSubstitutor, nonFixedToVariablesSubstitutor, storage.fixedTypeVariables
|
||||
)
|
||||
) {
|
||||
introducedConstraint = true
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user