From 0d9ed6990ed6ab8fae505bb32f3328bf484e57c1 Mon Sep 17 00:00:00 2001 From: Simon Ogorodnik Date: Wed, 17 Nov 2021 17:40:05 +0300 Subject: [PATCH] FIR: Build currentConstraintStorage for delegate inference incrementally --- .../fir/resolve/calls/CandidateFactory.kt | 2 +- .../AbstractManyCandidatesInferenceSession.kt | 2 +- .../inference/FirBuilderInferenceSession.kt | 2 +- .../FirDelegatedPropertyInferenceSession.kt | 127 +++++++----------- .../resolve/inference/FirInferenceSession.kt | 4 +- 5 files changed, 54 insertions(+), 83 deletions(-) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CandidateFactory.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CandidateFactory.kt index 7349c102696..b13ed045028 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CandidateFactory.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/CandidateFactory.kt @@ -34,7 +34,7 @@ class CandidateFactory private constructor( callInfo.arguments.forEach { system.addSubsystemFromExpression(it) } - system.addOtherSystem(context.bodyResolveContext.inferenceSession.currentConstraintSystem) + system.addOtherSystem(context.bodyResolveContext.inferenceSession.currentConstraintStorage) return system.asReadOnlyStorage() } } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/AbstractManyCandidatesInferenceSession.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/AbstractManyCandidatesInferenceSession.kt index 870ba04cba3..2a323ba8095 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/AbstractManyCandidatesInferenceSession.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/AbstractManyCandidatesInferenceSession.kt @@ -34,7 +34,7 @@ abstract class AbstractManyCandidatesInferenceSession( // do nothing } - final override fun addPartiallyResolvedCall(call: T) where T : FirResolvable, T : FirStatement { + override fun addPartiallyResolvedCall(call: T) where T : FirResolvable, T : FirStatement { partiallyResolvedCalls += call to call.candidate } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirBuilderInferenceSession.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirBuilderInferenceSession.kt index 44be722629b..47ae58694bf 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirBuilderInferenceSession.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirBuilderInferenceSession.kt @@ -37,7 +37,7 @@ class FirBuilderInferenceSession( ) : AbstractManyCandidatesInferenceSession(resolutionContext) { private val commonCalls: MutableList> = mutableListOf() - override val currentConstraintSystem: ConstraintStorage + override val currentConstraintStorage: ConstraintStorage get() = ConstraintStorage.Empty override fun isSyntheticTypeVariable(typeVariable: TypeVariableMarker): Boolean { diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirDelegatedPropertyInferenceSession.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirDelegatedPropertyInferenceSession.kt index f54bc37c451..c16ffe4b8a6 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirDelegatedPropertyInferenceSession.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirDelegatedPropertyInferenceSession.kt @@ -27,41 +27,9 @@ class FirDelegatedPropertyInferenceSession( private val postponedArgumentsAnalyzer: PostponedArgumentsAnalyzer, ) : AbstractManyCandidatesInferenceSession(resolutionContext) { - private var refreshConstraintStorage = true + private val currentConstraintSystem = components.session.inferenceComponents.createConstraintSystem() + override val currentConstraintStorage: ConstraintStorage get() = currentConstraintSystem.currentStorage() - private val system = components.session.inferenceComponents.createConstraintSystem() - - private var stubToTypeVariableSubstitutor: ConeSubstitutor = ConeSubstitutor.Empty - - private fun computeConstraintStorage(): ConstraintStorage { - stubToTypeVariableSubstitutor = createToSyntheticTypeVariableSubstitutor() - syntheticTypeVariableByTypeVariable.values.forEach { - system.registerVariable(it) - } - partiallyResolvedCalls.forEach { (_, candidate) -> - integrateConstraints( - system, - candidate.system.asReadOnlyStorage(), - stubToTypeVariableSubstitutor, - shouldIntegrateAllConstraints = false - ) - } - - return system.currentStorage() - } - - private lateinit var cachedConstraintStorage: ConstraintStorage - - override val currentConstraintSystem: ConstraintStorage - get() { - if (refreshConstraintStorage) { - refreshConstraintStorage = false - cachedConstraintStorage = computeConstraintStorage() - } - return cachedConstraintStorage - } - - private val commonSystem = components.session.inferenceComponents.createConstraintSystem() private val unitType: ConeKotlinType = components.session.builtinTypes.unitType.type private lateinit var resultingConstraintSystem: NewConstraintSystem @@ -71,14 +39,25 @@ class FirDelegatedPropertyInferenceSession( } } + fun integrateResolvedCall(storage: ConstraintStorage) { + registerSyntheticVariables(storage) + val stubToTypeVariableSubstitutor = createToSyntheticTypeVariableSubstitutor() + integrateConstraints( + currentConstraintSystem, + storage, + stubToTypeVariableSubstitutor, + false + ) + } + override fun addCompletedCall(call: T, candidate: Candidate) where T : FirResolvable, T : FirStatement { partiallyResolvedCalls += call to candidate - integrateConstraints( - system, - candidate.system.asReadOnlyStorage(), - stubToTypeVariableSubstitutor, - shouldIntegrateAllConstraints = false - ) + integrateResolvedCall(candidate.system.asReadOnlyStorage()) + } + + override fun addPartiallyResolvedCall(call: T) where T : FirResolvable, T : FirStatement { + super.addPartiallyResolvedCall(call) + integrateResolvedCall(call.candidate.system.currentStorage()) } override fun shouldRunCompletion(call: T): Boolean where T : FirResolvable, T : FirStatement { @@ -176,6 +155,8 @@ class FirDelegatedPropertyInferenceSession( } fun completeCandidates(): List { + val commonSystem = components.session.inferenceComponents.createConstraintSystem() + @Suppress("UNCHECKED_CAST") val notCompletedCalls = partiallyResolvedCalls.mapNotNull { partiallyResolvedCall -> partiallyResolvedCall.first.takeIf { resolvable -> @@ -185,7 +166,7 @@ class FirDelegatedPropertyInferenceSession( val stubToTypeVariableSubstitutor = createNonFixedTypeToVariableSubstitutor() - partiallyResolvedCalls.forEach { (call, candidate) -> + for ((call, candidate) in partiallyResolvedCalls) { integrateConstraints( commonSystem, candidate.system.asReadOnlyStorage(), @@ -238,43 +219,17 @@ class FirDelegatedPropertyInferenceSession( private val syntheticTypeVariableByTypeVariable = mutableMapOf() - - override fun createSyntheticStubTypes(system: NewConstraintSystemImpl): Map { - - val bindings = mutableMapOf() - -// val synthToOriginal = syntheticTypeVariableByTypeVariable.entries.associateBy({ it.value }, { it.key }) -// -// for (variable in system.postponedTypeVariables) { -// variable as ConeTypeVariable -// if (isSyntheticTypeVariable(variable)) { -// system.fixVariable( -// variable, -// ConeStubTypeForBuilderInference( -// synthToOriginal[variable]!! as ConeTypeVariable, -// ConeNullability.create(variable.defaultType.isMarkedNullable) -// ), -// ConeFixVariableConstraintPosition(variable) -// ) -// system.unmarkPostponedVariable(variable) -// } -// } - - for (variable in system.postponedTypeVariables) { - variable as ConeTypeVariable + private fun registerSyntheticVariables(storage: ConstraintStorage) { + for (variableWithConstraints in storage.notFixedTypeVariables.values) { + val variable = variableWithConstraints.typeVariable as ConeTypeVariable val syntheticVariable = syntheticTypeVariableByTypeVariable.getOrPut(variable) { - refreshConstraintStorage = true - ConeTypeVariable("_" + variable.typeConstructor.name) + ConeTypeVariable("_" + variable.typeConstructor.name).also { + currentConstraintSystem.registerVariable(it) + } } -// val potentialType = resolutionContext.inferenceComponents.resultTypeResolver.findResultType( -// system, -// system.notFixedTypeVariables[variable.typeConstructor]!!, -// TypeVariableDirectionCalculator.ResolveDirection.UNKNOWN -// ) - - bindings[variable.typeConstructor] = stubTypesByTypeVariable.getOrPut(variable) { + stubTypesByTypeVariable.getOrPut(variable) { ConeStubTypeForBuilderInference( syntheticVariable, ConeNullability.create(syntheticVariable.defaultType.isMarkedNullable) @@ -283,6 +238,17 @@ class FirDelegatedPropertyInferenceSession( } } } + } + + override fun createSyntheticStubTypes(system: NewConstraintSystemImpl): Map { + + val bindings = mutableMapOf() + + for (variable in system.postponedTypeVariables) { + variable as ConeTypeVariable + + bindings[variable.typeConstructor] = stubTypesByTypeVariable[variable]!! + } return bindings } @@ -302,9 +268,7 @@ class FirDelegatedPropertyInferenceSession( if (shouldIntegrateAllConstraints) { storage.notFixedTypeVariables.values.forEach { if (isSyntheticTypeVariable(it.typeVariable)) return@forEach - if (it.typeVariable.freshTypeConstructor(commonSystem.typeSystemContext) !in commonSystem.allTypeVariables) { - commonSystem.registerVariable(it.typeVariable) - } + commonSystem.registerTypeVariableIfNotPresent(it.typeVariable) } } /* @@ -347,7 +311,7 @@ class FirDelegatedPropertyInferenceSession( val typeVariable = storage.allTypeVariables.getValue(variableConstructor) if (isSyntheticTypeVariable(typeVariable)) continue - commonSystem.registerVariable(typeVariable) + commonSystem.registerTypeVariableIfNotPresent(typeVariable) commonSystem.addEqualityConstraint((typeVariable as ConeTypeVariable).defaultType, type, BuilderInferencePosition) introducedConstraint = true } @@ -356,3 +320,10 @@ class FirDelegatedPropertyInferenceSession( return introducedConstraint } } + + +fun NewConstraintSystemImpl.registerTypeVariableIfNotPresent(typeVariable: TypeVariableMarker) { + if (typeVariable.freshTypeConstructor(typeSystemContext) !in allTypeVariables) { + registerVariable(typeVariable) + } +} \ No newline at end of file diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirInferenceSession.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirInferenceSession.kt index 2f5337ea0f6..21b446cf1f8 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirInferenceSession.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirInferenceSession.kt @@ -25,7 +25,7 @@ abstract class FirInferenceSession { } abstract fun shouldRunCompletion(call: T): Boolean where T : FirResolvable, T : FirStatement - abstract val currentConstraintSystem: ConstraintStorage + abstract val currentConstraintStorage: ConstraintStorage abstract fun addPartiallyResolvedCall(call: T) where T : FirResolvable, T : FirStatement abstract fun addCompletedCall(call: T, candidate: Candidate) where T : FirResolvable, T : FirStatement @@ -52,7 +52,7 @@ abstract class FirInferenceSession { abstract class FirStubInferenceSession : FirInferenceSession() { override fun shouldRunCompletion(call: T): Boolean where T : FirResolvable, T : FirStatement = true - override val currentConstraintSystem: ConstraintStorage + override val currentConstraintStorage: ConstraintStorage get() = ConstraintStorage.Empty override fun addPartiallyResolvedCall(call: T) where T : FirResolvable, T : FirStatement {}