[NI] Prioritize variables with trivial constraints over complex ones

Consider the following constraint system (from the test example):

Nothing? <: V1
F!! <: V2
Inv<V1> <: S
Inv<V2> <: S

Where V1, V2, S are type variables, and F has nullable upper bound.
Type variable fixation order should be: V2 -> V1 -> S, and the problem
was that previously after fixation of type variable V2 we were trying
to fix S (before V1), so we had the following constraints on S:
Inv<F!!> <: S
Inv<V1> <: S
=> S were fixed to Inv<F!!>

And after this V1 was fixed to F!! which is contradictory as Nothing?
is not a subtype of F!!.

 #KT-33033 Fixed
This commit is contained in:
Mikhail Zarechenskiy
2019-11-01 15:50:48 +03:00
parent 5582fd4056
commit 650e2501bb
6 changed files with 51 additions and 2 deletions
@@ -52,8 +52,8 @@ class VariableFixationFinder(
private enum class TypeVariableFixationReadiness {
FORBIDDEN,
WITHOUT_PROPER_ARGUMENT_CONSTRAINT, // proper constraint from arguments -- not from upper bound for type parameters
WITH_TRIVIAL_OR_NON_PROPER_CONSTRAINTS, // proper trivial constraint from arguments, Nothing <: T
WITH_COMPLEX_DEPENDENCY, // if type variable T has constraint with non fixed type variable inside (non-top-level): T <: Foo<S>
WITH_TRIVIAL_OR_NON_PROPER_CONSTRAINTS, // proper trivial constraint from arguments, Nothing <: T
RELATED_TO_ANY_OUTPUT_TYPE,
READY_FOR_FIXATION,
}
@@ -65,8 +65,8 @@ class VariableFixationFinder(
!notFixedTypeVariables.contains(variable) ||
dependencyProvider.isVariableRelatedToTopLevelType(variable) -> TypeVariableFixationReadiness.FORBIDDEN
!variableHasProperArgumentConstraints(variable) -> TypeVariableFixationReadiness.WITHOUT_PROPER_ARGUMENT_CONSTRAINT
variableHasTrivialOrNonProperConstraints(variable) -> TypeVariableFixationReadiness.WITH_TRIVIAL_OR_NON_PROPER_CONSTRAINTS
hasDependencyToOtherTypeVariables(variable) -> TypeVariableFixationReadiness.WITH_COMPLEX_DEPENDENCY
variableHasTrivialOrNonProperConstraints(variable) -> TypeVariableFixationReadiness.WITH_TRIVIAL_OR_NON_PROPER_CONSTRAINTS
dependencyProvider.isVariableRelatedToAnyOutputType(variable) -> TypeVariableFixationReadiness.RELATED_TO_ANY_OUTPUT_TYPE
else -> TypeVariableFixationReadiness.READY_FOR_FIXATION
}