Add type variables into common system of a builder inference call properly
This commit is contained in:
+19
-16
@@ -32,6 +32,8 @@ import org.jetbrains.kotlin.types.*
|
|||||||
import org.jetbrains.kotlin.types.checker.NewCapturedType
|
import org.jetbrains.kotlin.types.checker.NewCapturedType
|
||||||
import org.jetbrains.kotlin.types.expressions.DoubleColonExpressionResolver
|
import org.jetbrains.kotlin.types.expressions.DoubleColonExpressionResolver
|
||||||
import org.jetbrains.kotlin.types.expressions.ExpressionTypingServices
|
import org.jetbrains.kotlin.types.expressions.ExpressionTypingServices
|
||||||
|
import org.jetbrains.kotlin.types.model.freshTypeConstructor
|
||||||
|
import org.jetbrains.kotlin.types.model.safeSubstitute
|
||||||
import org.jetbrains.kotlin.types.typeUtil.asTypeProjection
|
import org.jetbrains.kotlin.types.typeUtil.asTypeProjection
|
||||||
import org.jetbrains.kotlin.types.typeUtil.contains
|
import org.jetbrains.kotlin.types.typeUtil.contains
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.cast
|
import org.jetbrains.kotlin.utils.addToStdlib.cast
|
||||||
@@ -59,12 +61,13 @@ class BuilderInferenceSession(
|
|||||||
private var nestedBuilderInferenceSessions: MutableSet<BuilderInferenceSession> = mutableSetOf()
|
private var nestedBuilderInferenceSessions: MutableSet<BuilderInferenceSession> = mutableSetOf()
|
||||||
|
|
||||||
private lateinit var lambda: ResolvedLambdaAtom
|
private lateinit var lambda: ResolvedLambdaAtom
|
||||||
private lateinit var commonSystem: NewConstraintSystemImpl
|
private val commonSystem = NewConstraintSystemImpl(callComponents.constraintInjector, builtIns)
|
||||||
|
|
||||||
init {
|
init {
|
||||||
if (topLevelCallContext.inferenceSession is BuilderInferenceSession) {
|
if (topLevelCallContext.inferenceSession is BuilderInferenceSession) {
|
||||||
topLevelCallContext.inferenceSession.nestedBuilderInferenceSessions.add(this)
|
topLevelCallContext.inferenceSession.nestedBuilderInferenceSessions.add(this)
|
||||||
}
|
}
|
||||||
|
stubsForPostponedVariables.keys.forEach(commonSystem::registerVariable)
|
||||||
}
|
}
|
||||||
|
|
||||||
private val commonCalls = arrayListOf<PSICompletedCallInfo>()
|
private val commonCalls = arrayListOf<PSICompletedCallInfo>()
|
||||||
@@ -195,11 +198,10 @@ class BuilderInferenceSession(
|
|||||||
completionMode: ConstraintSystemCompletionMode,
|
completionMode: ConstraintSystemCompletionMode,
|
||||||
diagnosticsHolder: KotlinDiagnosticsHolder,
|
diagnosticsHolder: KotlinDiagnosticsHolder,
|
||||||
): Map<TypeConstructor, UnwrappedType>? {
|
): Map<TypeConstructor, UnwrappedType>? {
|
||||||
val (commonSystem, effectivelyEmptyConstraintSystem) = buildCommonSystem(initialStorage)
|
val effectivelyEmptyConstraintSystem = initializeCommonSystem(initialStorage)
|
||||||
val initialStorageSubstitutor = initialStorage.buildResultingSubstitutor(commonSystem, transformTypeVariablesToErrorTypes = false)
|
val initialStorageSubstitutor = initialStorage.buildResultingSubstitutor(commonSystem, transformTypeVariablesToErrorTypes = false)
|
||||||
|
|
||||||
this.lambda = lambda
|
this.lambda = lambda
|
||||||
this.commonSystem = commonSystem
|
|
||||||
|
|
||||||
if (effectivelyEmptyConstraintSystem) {
|
if (effectivelyEmptyConstraintSystem) {
|
||||||
if (isTopLevelBuilderInferenceCall()) {
|
if (isTopLevelBuilderInferenceCall()) {
|
||||||
@@ -262,12 +264,15 @@ class BuilderInferenceSession(
|
|||||||
private fun createNonFixedTypeToVariableSubstitutor() = NewTypeSubstitutorByConstructorMap(createNonFixedTypeToVariableMap())
|
private fun createNonFixedTypeToVariableSubstitutor() = NewTypeSubstitutorByConstructorMap(createNonFixedTypeToVariableMap())
|
||||||
|
|
||||||
private fun integrateConstraints(
|
private fun integrateConstraints(
|
||||||
commonSystem: NewConstraintSystemImpl,
|
|
||||||
storage: ConstraintStorage,
|
storage: ConstraintStorage,
|
||||||
nonFixedToVariablesSubstitutor: NewTypeSubstitutor,
|
nonFixedToVariablesSubstitutor: NewTypeSubstitutor,
|
||||||
shouldIntegrateAllConstraints: Boolean
|
shouldIntegrateAllConstraints: Boolean
|
||||||
): Boolean {
|
): Boolean {
|
||||||
storage.notFixedTypeVariables.values.forEach { commonSystem.registerVariable(it.typeVariable) }
|
storage.notFixedTypeVariables.values.forEach {
|
||||||
|
if (it.typeVariable.freshTypeConstructor(commonSystem.typeSystemContext) !in commonSystem.allTypeVariables) {
|
||||||
|
commonSystem.registerVariable(it.typeVariable)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (parentSession in findAllParentBuildInferenceSessions()) {
|
for (parentSession in findAllParentBuildInferenceSessions()) {
|
||||||
parentSession.stubsForPostponedVariables.keys.forEach { commonSystem.registerVariable(it) }
|
parentSession.stubsForPostponedVariables.keys.forEach { commonSystem.registerVariable(it) }
|
||||||
@@ -338,41 +343,39 @@ class BuilderInferenceSession(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun extractCommonCapturedTypes(a: KotlinType, b: KotlinType): List<NewCapturedType> {
|
private fun extractCommonCapturedTypes(a: KotlinType, b: KotlinType): List<NewCapturedType> {
|
||||||
val extractedCapturedTypes = mutableSetOf<NewCapturedType>().also { extractCapturedTypes(a, it) }
|
val extractedCapturedTypes = mutableSetOf<NewCapturedType>().also { extractCapturedTypesTo(a, it) }
|
||||||
return extractedCapturedTypes.filter { capturedType -> b.contains { it.constructor === capturedType.constructor } }
|
return extractedCapturedTypes.filter { capturedType -> b.contains { it.constructor === capturedType.constructor } }
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun extractCapturedTypes(type: KotlinType, capturedTypes: MutableSet<NewCapturedType>) {
|
private fun extractCapturedTypesTo(type: KotlinType, to: MutableSet<NewCapturedType>) {
|
||||||
if (type is NewCapturedType) {
|
if (type is NewCapturedType) {
|
||||||
capturedTypes.add(type)
|
to.add(type)
|
||||||
}
|
}
|
||||||
for (typeArgument in type.arguments) {
|
for (typeArgument in type.arguments) {
|
||||||
if (typeArgument.isStarProjection) continue
|
if (typeArgument.isStarProjection) continue
|
||||||
extractCapturedTypes(typeArgument.type, capturedTypes)
|
extractCapturedTypesTo(typeArgument.type, to)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun buildCommonSystem(initialStorage: ConstraintStorage): Pair<NewConstraintSystemImpl, Boolean> {
|
private fun initializeCommonSystem(initialStorage: ConstraintStorage): Boolean {
|
||||||
val commonSystem = NewConstraintSystemImpl(callComponents.constraintInjector, builtIns)
|
|
||||||
|
|
||||||
val nonFixedToVariablesSubstitutor = createNonFixedTypeToVariableSubstitutor()
|
val nonFixedToVariablesSubstitutor = createNonFixedTypeToVariableSubstitutor()
|
||||||
|
|
||||||
integrateConstraints(commonSystem, initialStorage, nonFixedToVariablesSubstitutor, false)
|
integrateConstraints(initialStorage, nonFixedToVariablesSubstitutor, false)
|
||||||
|
|
||||||
var effectivelyEmptyCommonSystem = true
|
var effectivelyEmptyCommonSystem = true
|
||||||
|
|
||||||
for (call in commonCalls) {
|
for (call in commonCalls) {
|
||||||
val hasConstraints =
|
val hasConstraints =
|
||||||
integrateConstraints(commonSystem, call.callResolutionResult.constraintSystem, nonFixedToVariablesSubstitutor, false)
|
integrateConstraints(call.callResolutionResult.constraintSystem, nonFixedToVariablesSubstitutor, false)
|
||||||
if (hasConstraints) effectivelyEmptyCommonSystem = false
|
if (hasConstraints) effectivelyEmptyCommonSystem = false
|
||||||
}
|
}
|
||||||
for (call in partiallyResolvedCallsInfo) {
|
for (call in partiallyResolvedCallsInfo) {
|
||||||
val hasConstraints =
|
val hasConstraints =
|
||||||
integrateConstraints(commonSystem, call.callResolutionResult.constraintSystem, nonFixedToVariablesSubstitutor, true)
|
integrateConstraints(call.callResolutionResult.constraintSystem, nonFixedToVariablesSubstitutor, true)
|
||||||
if (hasConstraints) effectivelyEmptyCommonSystem = false
|
if (hasConstraints) effectivelyEmptyCommonSystem = false
|
||||||
}
|
}
|
||||||
|
|
||||||
return commonSystem to effectivelyEmptyCommonSystem
|
return effectivelyEmptyCommonSystem
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun reportErrors(completedCall: CallInfo, resolvedCall: ResolvedCall<*>, errors: List<ConstraintSystemError>) {
|
private fun reportErrors(completedCall: CallInfo, resolvedCall: ResolvedCall<*>, errors: List<ConstraintSystemError>) {
|
||||||
|
|||||||
Reference in New Issue
Block a user