K2: change logic of result type search in ILT case

Related to KT-57487, KT-57703
This commit is contained in:
Mikhail Glukhikh
2023-03-30 12:13:32 +02:00
committed by Space Team
parent 27c4a7b7ef
commit 08c22c388c
10 changed files with 128 additions and 7 deletions
@@ -68,17 +68,40 @@ class ResultTypeResolver(
variableWithConstraints: VariableWithConstraints,
direction: ResolveDirection
): KotlinTypeMarker? {
findResultIfThereIsEqualsConstraint(c, variableWithConstraints)?.let { return it }
val resultTypeFromEqualConstraint = findResultIfThereIsEqualsConstraint(c, variableWithConstraints)
if (resultTypeFromEqualConstraint != null) {
with(c) {
if (!isK2 || !resultTypeFromEqualConstraint.contains { type ->
type.typeConstructor().isIntegerLiteralConstantTypeConstructor()
}
) {
// In K2, we don't return here ILT-based types immediately
return resultTypeFromEqualConstraint
}
}
}
val subType = c.findSubType(variableWithConstraints)
// Super type should be the most flexible, sub type should be the least one
val superType = c.findSuperType(variableWithConstraints).makeFlexibleIfNecessary(c, variableWithConstraints.constraints)
return if (direction == ResolveDirection.TO_SUBTYPE || direction == ResolveDirection.UNKNOWN) {
val resultTypeFromDirection = if (direction == ResolveDirection.TO_SUBTYPE || direction == ResolveDirection.UNKNOWN) {
c.resultType(subType, superType, variableWithConstraints)
} else {
c.resultType(superType, subType, variableWithConstraints)
}
// In the general case, we can have here two types, one from EQUAL constraint which must be ILT-based,
// and the second one from UPPER/LOWER constraints (subType/superType based)
// The logic of choice here is:
// - if one type is null, we return another one
// - we return type from UPPER/LOWER constraints if it's more precise
// - otherwise we return ILT-based type
return when {
resultTypeFromEqualConstraint == null -> resultTypeFromDirection
resultTypeFromDirection == null -> resultTypeFromEqualConstraint
AbstractTypeChecker.isSubtypeOf(c, resultTypeFromDirection, resultTypeFromEqualConstraint) -> resultTypeFromDirection
else -> resultTypeFromEqualConstraint
}
}
/*