[FE] Substitute fixed type variables with inferred stub types

Actually, a type variable might be fixed into a stub type. Such stub type should be substituted before sub calls completion

^KT-51988 Fixed
This commit is contained in:
Victor Petukhov
2022-05-05 11:36:39 +02:00
committed by teamcity
parent 92df5cd67f
commit 6027c2a9aa
19 changed files with 133 additions and 27 deletions
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.visitors.FirDefaultTransformer
import org.jetbrains.kotlin.fir.visitors.transformSingle
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemBuilder
import org.jetbrains.kotlin.resolve.calls.inference.buildAbstractResultingSubstitutor
import org.jetbrains.kotlin.resolve.calls.inference.components.ConstraintSystemCompletionMode
import org.jetbrains.kotlin.resolve.calls.inference.model.*
@@ -108,12 +109,14 @@ class FirBuilderInferenceSession(
override fun inferPostponedVariables(
lambda: ResolvedLambdaAtom,
initialStorage: ConstraintStorage,
constraintSystemBuilder: ConstraintSystemBuilder,
completionMode: ConstraintSystemCompletionMode
): Map<ConeTypeVariableTypeConstructor, ConeKotlinType>? {
val (commonSystem, effectivelyEmptyConstraintSystem) = buildCommonSystem(initialStorage)
val (commonSystem, effectivelyEmptyConstraintSystem) = buildCommonSystem(constraintSystemBuilder.currentStorage())
val resultingSubstitutor by lazy { getResultingSubstitutor(commonSystem) }
if (effectivelyEmptyConstraintSystem) {
updateCalls(commonSystem)
updateCalls(resultingSubstitutor)
return null
}
@@ -129,7 +132,11 @@ class FirBuilderInferenceSession(
error("Shouldn't be called in complete constraint system mode")
}
updateCalls(commonSystem)
if (completionMode == ConstraintSystemCompletionMode.FULL) {
constraintSystemBuilder.substituteFixedVariables(resultingSubstitutor)
}
updateCalls(resultingSubstitutor)
@Suppress("UNCHECKED_CAST")
return commonSystem.fixedTypeVariables as Map<ConeTypeVariableTypeConstructor, ConeKotlinType>
@@ -217,16 +224,18 @@ class FirBuilderInferenceSession(
return introducedConstraint
}
private fun updateCalls(commonSystem: NewConstraintSystemImpl) {
private fun getResultingSubstitutor(commonSystem: NewConstraintSystemImpl): ChainedSubstitutor {
val nonFixedToVariablesSubstitutor = createNonFixedTypeToVariableSubstitutor()
val commonSystemSubstitutor = commonSystem.buildCurrentSubstitutor() as ConeSubstitutor
val nonFixedTypesToResultSubstitutor = ChainedSubstitutor(nonFixedToVariablesSubstitutor, commonSystemSubstitutor)
return ChainedSubstitutor(nonFixedToVariablesSubstitutor, commonSystemSubstitutor)
}
val stubTypeSubstitutor = FirStubTypeTransformer(nonFixedTypesToResultSubstitutor)
private fun updateCalls(substitutor: ConeSubstitutor) {
val stubTypeSubstitutor = FirStubTypeTransformer(substitutor)
lambda.transformSingle(stubTypeSubstitutor, null)
// TODO: support diagnostics, see [CoroutineInferenceSession#updateCalls]
val completionResultsWriter = components.callCompleter.createCompletionResultsWriter(nonFixedTypesToResultSubstitutor)
val completionResultsWriter = components.callCompleter.createCompletionResultsWriter(substitutor)
for ((call, _) in partiallyResolvedCalls) {
call.transformSingle(completionResultsWriter, null)
// TODO: support diagnostics, see [CoroutineInferenceSession#updateCalls]
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.fir.resolve.substitution.ChainedSubstitutor
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
import org.jetbrains.kotlin.fir.resolve.substitution.NotFixedTypeToVariableSubstitutorForDelegateInference
import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemBuilder
import org.jetbrains.kotlin.resolve.calls.inference.NewConstraintSystem
import org.jetbrains.kotlin.resolve.calls.inference.buildAbstractResultingSubstitutor
import org.jetbrains.kotlin.resolve.calls.inference.components.ConstraintSystemCompletionContext
@@ -108,7 +109,7 @@ class FirDelegatedPropertyInferenceSession(
override fun inferPostponedVariables(
lambda: ResolvedLambdaAtom,
initialStorage: ConstraintStorage,
constraintSystemBuilder: ConstraintSystemBuilder,
completionMode: ConstraintSystemCompletionMode
): Map<ConeTypeVariableTypeConstructor, ConeKotlinType>? = null
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.fir.resolve.calls.Candidate
import org.jetbrains.kotlin.fir.types.ConeKotlinType
import org.jetbrains.kotlin.fir.types.ConeStubType
import org.jetbrains.kotlin.fir.types.ConeTypeVariableTypeConstructor
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemBuilder
import org.jetbrains.kotlin.resolve.calls.inference.components.ConstraintSystemCompletionContext
import org.jetbrains.kotlin.resolve.calls.inference.components.ConstraintSystemCompletionMode
import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintStorage
@@ -41,7 +42,7 @@ abstract class FirInferenceSession {
abstract fun inferPostponedVariables(
lambda: ResolvedLambdaAtom,
initialStorage: ConstraintStorage,
constraintSystemBuilder: ConstraintSystemBuilder,
completionMode: ConstraintSystemCompletionMode,
// TODO: diagnostic holder
): Map<ConeTypeVariableTypeConstructor, ConeKotlinType>?
@@ -61,7 +62,7 @@ abstract class FirStubInferenceSession : FirInferenceSession() {
override fun inferPostponedVariables(
lambda: ResolvedLambdaAtom,
initialStorage: ConstraintStorage,
constraintSystemBuilder: ConstraintSystemBuilder,
completionMode: ConstraintSystemCompletionMode
): Map<ConeTypeVariableTypeConstructor, ConeKotlinType>? = null
@@ -209,9 +209,8 @@ class PostponedArgumentsAnalyzer(
lambda.returnStatements = returnArguments
if (inferenceSession != null) {
val storageSnapshot = c.getBuilder().currentStorage()
val postponedVariables = inferenceSession.inferPostponedVariables(lambda, storageSnapshot, completionMode)
val constraintSystemBuilder = c.getBuilder()
val postponedVariables = inferenceSession.inferPostponedVariables(lambda, constraintSystemBuilder, completionMode)
if (postponedVariables == null) {
c.getBuilder().removePostponedVariables()
@@ -219,7 +218,7 @@ class PostponedArgumentsAnalyzer(
}
for ((constructor, resultType) in postponedVariables) {
val variableWithConstraints = storageSnapshot.notFixedTypeVariables[constructor] ?: continue
val variableWithConstraints = constraintSystemBuilder.currentStorage().notFixedTypeVariables[constructor] ?: continue
val variable = variableWithConstraints.typeVariable as ConeTypeVariable
c.getBuilder().unmarkPostponedVariable(variable)