Stop subtyping constraint search if equality constraints for...
all not fixed type vars are found #KT-35626 fixed
This commit is contained in:
+27
-10
@@ -17,6 +17,7 @@
|
||||
package org.jetbrains.kotlin.resolve.calls.inference.components
|
||||
|
||||
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemOperation
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.model.*
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintKind.LOWER
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintKind.UPPER
|
||||
@@ -26,6 +27,7 @@ import org.jetbrains.kotlin.types.checker.KotlinTypeRefiner
|
||||
import org.jetbrains.kotlin.types.model.*
|
||||
import org.jetbrains.kotlin.types.refinement.TypeRefinement
|
||||
import java.util.*
|
||||
import kotlin.collections.ArrayList
|
||||
import kotlin.math.max
|
||||
|
||||
class ConstraintInjector(
|
||||
@@ -69,23 +71,38 @@ class ConstraintInjector(
|
||||
upperType: KotlinTypeMarker,
|
||||
incorporatePosition: IncorporationConstraintPosition
|
||||
) {
|
||||
val possibleNewConstraints = Stack<Pair<TypeVariableMarker, Constraint>>()
|
||||
val possibleNewConstraints = ArrayList<Pair<TypeVariableMarker, Constraint>>()
|
||||
val typeCheckerContext = TypeCheckerContext(c, incorporatePosition, lowerType, upperType, possibleNewConstraints)
|
||||
typeCheckerContext.runIsSubtypeOf(lowerType, upperType)
|
||||
|
||||
while (possibleNewConstraints.isNotEmpty()) {
|
||||
val (typeVariable, constraint) = possibleNewConstraints.pop()
|
||||
if (c.shouldWeSkipConstraint(typeVariable, constraint)) continue
|
||||
|
||||
val constraints =
|
||||
c.notFixedTypeVariables[typeVariable.freshTypeConstructor(c)] ?: typeCheckerContext.fixedTypeVariable(typeVariable)
|
||||
val constraintsToProcess = possibleNewConstraints.toTypedArray()
|
||||
possibleNewConstraints.clear()
|
||||
for ((typeVariable, constraint) in constraintsToProcess) {
|
||||
if (c.shouldWeSkipConstraint(typeVariable, constraint)) continue
|
||||
|
||||
// it is important, that we add constraint here(not inside TypeCheckerContext), because inside incorporation we read constraints
|
||||
constraints.addConstraint(constraint)?.let {
|
||||
if (!constraint.isNullabilityConstraint) {
|
||||
constraintIncorporator.incorporate(typeCheckerContext, typeVariable, it)
|
||||
val constraints =
|
||||
c.notFixedTypeVariables[typeVariable.freshTypeConstructor(c)] ?: typeCheckerContext.fixedTypeVariable(typeVariable)
|
||||
|
||||
// it is important, that we add constraint here(not inside TypeCheckerContext), because inside incorporation we read constraints
|
||||
constraints.addConstraint(constraint)?.let {
|
||||
if (!constraint.isNullabilityConstraint) {
|
||||
constraintIncorporator.incorporate(typeCheckerContext, typeVariable, it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val contextOps = c as? ConstraintSystemOperation
|
||||
if (possibleNewConstraints == null ||
|
||||
(contextOps != null && c.notFixedTypeVariables.all { typeVariable ->
|
||||
typeVariable.value.constraints.any { constraint ->
|
||||
constraint.kind == ConstraintKind.EQUALITY && contextOps.isProperType(constraint.type)
|
||||
}
|
||||
})
|
||||
) {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -122,7 +139,7 @@ class ConstraintInjector(
|
||||
val position: IncorporationConstraintPosition,
|
||||
val baseLowerType: KotlinTypeMarker,
|
||||
val baseUpperType: KotlinTypeMarker,
|
||||
val possibleNewConstraints: MutableList<Pair<TypeVariableMarker, Constraint>>
|
||||
val possibleNewConstraints: MutableCollection<Pair<TypeVariableMarker, Constraint>>
|
||||
) : AbstractTypeCheckerContextForConstraintSystem(), ConstraintIncorporator.Context, TypeSystemInferenceExtensionContext by c {
|
||||
|
||||
val baseContext: AbstractTypeCheckerContext = newBaseTypeCheckerContext(isErrorTypeEqualsToAnything, isStubTypeEqualsToAnything)
|
||||
|
||||
Reference in New Issue
Block a user