FIR: Build currentConstraintStorage for delegate inference incrementally

This commit is contained in:
Simon Ogorodnik
2021-11-17 17:40:05 +03:00
committed by teamcity
parent a4df0aaa7d
commit 0d9ed6990e
5 changed files with 54 additions and 83 deletions
@@ -34,7 +34,7 @@ class CandidateFactory private constructor(
callInfo.arguments.forEach { callInfo.arguments.forEach {
system.addSubsystemFromExpression(it) system.addSubsystemFromExpression(it)
} }
system.addOtherSystem(context.bodyResolveContext.inferenceSession.currentConstraintSystem) system.addOtherSystem(context.bodyResolveContext.inferenceSession.currentConstraintStorage)
return system.asReadOnlyStorage() return system.asReadOnlyStorage()
} }
} }
@@ -34,7 +34,7 @@ abstract class AbstractManyCandidatesInferenceSession(
// do nothing // do nothing
} }
final override fun <T> addPartiallyResolvedCall(call: T) where T : FirResolvable, T : FirStatement { override fun <T> addPartiallyResolvedCall(call: T) where T : FirResolvable, T : FirStatement {
partiallyResolvedCalls += call to call.candidate partiallyResolvedCalls += call to call.candidate
} }
@@ -37,7 +37,7 @@ class FirBuilderInferenceSession(
) : AbstractManyCandidatesInferenceSession(resolutionContext) { ) : AbstractManyCandidatesInferenceSession(resolutionContext) {
private val commonCalls: MutableList<Pair<FirStatement, Candidate>> = mutableListOf() private val commonCalls: MutableList<Pair<FirStatement, Candidate>> = mutableListOf()
override val currentConstraintSystem: ConstraintStorage override val currentConstraintStorage: ConstraintStorage
get() = ConstraintStorage.Empty get() = ConstraintStorage.Empty
override fun isSyntheticTypeVariable(typeVariable: TypeVariableMarker): Boolean { override fun isSyntheticTypeVariable(typeVariable: TypeVariableMarker): Boolean {
@@ -27,41 +27,9 @@ class FirDelegatedPropertyInferenceSession(
private val postponedArgumentsAnalyzer: PostponedArgumentsAnalyzer, private val postponedArgumentsAnalyzer: PostponedArgumentsAnalyzer,
) : AbstractManyCandidatesInferenceSession(resolutionContext) { ) : 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 val unitType: ConeKotlinType = components.session.builtinTypes.unitType.type
private lateinit var resultingConstraintSystem: NewConstraintSystem 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 <T> addCompletedCall(call: T, candidate: Candidate) where T : FirResolvable, T : FirStatement { override fun <T> addCompletedCall(call: T, candidate: Candidate) where T : FirResolvable, T : FirStatement {
partiallyResolvedCalls += call to candidate partiallyResolvedCalls += call to candidate
integrateConstraints( integrateResolvedCall(candidate.system.asReadOnlyStorage())
system, }
candidate.system.asReadOnlyStorage(),
stubToTypeVariableSubstitutor, override fun <T> addPartiallyResolvedCall(call: T) where T : FirResolvable, T : FirStatement {
shouldIntegrateAllConstraints = false super.addPartiallyResolvedCall(call)
) integrateResolvedCall(call.candidate.system.currentStorage())
} }
override fun <T> shouldRunCompletion(call: T): Boolean where T : FirResolvable, T : FirStatement { override fun <T> shouldRunCompletion(call: T): Boolean where T : FirResolvable, T : FirStatement {
@@ -176,6 +155,8 @@ class FirDelegatedPropertyInferenceSession(
} }
fun completeCandidates(): List<FirResolvable> { fun completeCandidates(): List<FirResolvable> {
val commonSystem = components.session.inferenceComponents.createConstraintSystem()
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
val notCompletedCalls = partiallyResolvedCalls.mapNotNull { partiallyResolvedCall -> val notCompletedCalls = partiallyResolvedCalls.mapNotNull { partiallyResolvedCall ->
partiallyResolvedCall.first.takeIf { resolvable -> partiallyResolvedCall.first.takeIf { resolvable ->
@@ -185,7 +166,7 @@ class FirDelegatedPropertyInferenceSession(
val stubToTypeVariableSubstitutor = createNonFixedTypeToVariableSubstitutor() val stubToTypeVariableSubstitutor = createNonFixedTypeToVariableSubstitutor()
partiallyResolvedCalls.forEach { (call, candidate) -> for ((call, candidate) in partiallyResolvedCalls) {
integrateConstraints( integrateConstraints(
commonSystem, commonSystem,
candidate.system.asReadOnlyStorage(), candidate.system.asReadOnlyStorage(),
@@ -238,43 +219,17 @@ class FirDelegatedPropertyInferenceSession(
private val syntheticTypeVariableByTypeVariable = mutableMapOf<TypeVariableMarker, ConeTypeVariable>() private val syntheticTypeVariableByTypeVariable = mutableMapOf<TypeVariableMarker, ConeTypeVariable>()
private fun registerSyntheticVariables(storage: ConstraintStorage) {
override fun createSyntheticStubTypes(system: NewConstraintSystemImpl): Map<TypeConstructorMarker, ConeStubType> { for (variableWithConstraints in storage.notFixedTypeVariables.values) {
val variable = variableWithConstraints.typeVariable as ConeTypeVariable
val bindings = mutableMapOf<TypeConstructorMarker, ConeStubType>()
// 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
val syntheticVariable = syntheticTypeVariableByTypeVariable.getOrPut(variable) { val syntheticVariable = syntheticTypeVariableByTypeVariable.getOrPut(variable) {
refreshConstraintStorage = true ConeTypeVariable("_" + variable.typeConstructor.name).also {
ConeTypeVariable("_" + variable.typeConstructor.name) currentConstraintSystem.registerVariable(it)
}
} }
// val potentialType = resolutionContext.inferenceComponents.resultTypeResolver.findResultType( stubTypesByTypeVariable.getOrPut(variable) {
// system,
// system.notFixedTypeVariables[variable.typeConstructor]!!,
// TypeVariableDirectionCalculator.ResolveDirection.UNKNOWN
// )
bindings[variable.typeConstructor] = stubTypesByTypeVariable.getOrPut(variable) {
ConeStubTypeForBuilderInference( ConeStubTypeForBuilderInference(
syntheticVariable, syntheticVariable,
ConeNullability.create(syntheticVariable.defaultType.isMarkedNullable) ConeNullability.create(syntheticVariable.defaultType.isMarkedNullable)
@@ -283,6 +238,17 @@ class FirDelegatedPropertyInferenceSession(
} }
} }
} }
}
override fun createSyntheticStubTypes(system: NewConstraintSystemImpl): Map<TypeConstructorMarker, ConeStubType> {
val bindings = mutableMapOf<TypeConstructorMarker, ConeStubType>()
for (variable in system.postponedTypeVariables) {
variable as ConeTypeVariable
bindings[variable.typeConstructor] = stubTypesByTypeVariable[variable]!!
}
return bindings return bindings
} }
@@ -302,9 +268,7 @@ class FirDelegatedPropertyInferenceSession(
if (shouldIntegrateAllConstraints) { if (shouldIntegrateAllConstraints) {
storage.notFixedTypeVariables.values.forEach { storage.notFixedTypeVariables.values.forEach {
if (isSyntheticTypeVariable(it.typeVariable)) return@forEach if (isSyntheticTypeVariable(it.typeVariable)) return@forEach
if (it.typeVariable.freshTypeConstructor(commonSystem.typeSystemContext) !in commonSystem.allTypeVariables) { commonSystem.registerTypeVariableIfNotPresent(it.typeVariable)
commonSystem.registerVariable(it.typeVariable)
}
} }
} }
/* /*
@@ -347,7 +311,7 @@ class FirDelegatedPropertyInferenceSession(
val typeVariable = storage.allTypeVariables.getValue(variableConstructor) val typeVariable = storage.allTypeVariables.getValue(variableConstructor)
if (isSyntheticTypeVariable(typeVariable)) continue if (isSyntheticTypeVariable(typeVariable)) continue
commonSystem.registerVariable(typeVariable) commonSystem.registerTypeVariableIfNotPresent(typeVariable)
commonSystem.addEqualityConstraint((typeVariable as ConeTypeVariable).defaultType, type, BuilderInferencePosition) commonSystem.addEqualityConstraint((typeVariable as ConeTypeVariable).defaultType, type, BuilderInferencePosition)
introducedConstraint = true introducedConstraint = true
} }
@@ -356,3 +320,10 @@ class FirDelegatedPropertyInferenceSession(
return introducedConstraint return introducedConstraint
} }
} }
fun NewConstraintSystemImpl.registerTypeVariableIfNotPresent(typeVariable: TypeVariableMarker) {
if (typeVariable.freshTypeConstructor(typeSystemContext) !in allTypeVariables) {
registerVariable(typeVariable)
}
}
@@ -25,7 +25,7 @@ abstract class FirInferenceSession {
} }
abstract fun <T> shouldRunCompletion(call: T): Boolean where T : FirResolvable, T : FirStatement abstract fun <T> shouldRunCompletion(call: T): Boolean where T : FirResolvable, T : FirStatement
abstract val currentConstraintSystem: ConstraintStorage abstract val currentConstraintStorage: ConstraintStorage
abstract fun <T> addPartiallyResolvedCall(call: T) where T : FirResolvable, T : FirStatement abstract fun <T> addPartiallyResolvedCall(call: T) where T : FirResolvable, T : FirStatement
abstract fun <T> addCompletedCall(call: T, candidate: Candidate) where T : FirResolvable, T : FirStatement abstract fun <T> addCompletedCall(call: T, candidate: Candidate) where T : FirResolvable, T : FirStatement
@@ -52,7 +52,7 @@ abstract class FirInferenceSession {
abstract class FirStubInferenceSession : FirInferenceSession() { abstract class FirStubInferenceSession : FirInferenceSession() {
override fun <T> shouldRunCompletion(call: T): Boolean where T : FirResolvable, T : FirStatement = true override fun <T> shouldRunCompletion(call: T): Boolean where T : FirResolvable, T : FirStatement = true
override val currentConstraintSystem: ConstraintStorage override val currentConstraintStorage: ConstraintStorage
get() = ConstraintStorage.Empty get() = ConstraintStorage.Empty
override fun <T> addPartiallyResolvedCall(call: T) where T : FirResolvable, T : FirStatement {} override fun <T> addPartiallyResolvedCall(call: T) where T : FirResolvable, T : FirStatement {}