Propagate nullness flexibility into the result type from type variables in other constraints during result type finding, to prevent variable fixation to less flexible type
^KT-44540 Fixed
This commit is contained in:
+27
-1
@@ -40,7 +40,9 @@ class ResultTypeResolver(
|
||||
findResultIfThereIsEqualsConstraint(c, variableWithConstraints)?.let { return it }
|
||||
|
||||
val subType = c.findSubType(variableWithConstraints)
|
||||
val superType = c.findSuperType(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) {
|
||||
c.resultType(subType, superType, variableWithConstraints)
|
||||
} else {
|
||||
@@ -48,6 +50,30 @@ class ResultTypeResolver(
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* We propagate nullness flexibility into the result type from type variables in other constraints
|
||||
* to prevent variable fixation into less flexible type.
|
||||
* Constraints:
|
||||
* UPPER(TypeVariable(T)..TypeVariable(T)?)
|
||||
* UPPER(Foo?)
|
||||
* Result type = makeFlexibleIfNecessary(Foo?) = Foo!
|
||||
*
|
||||
* We don't propagate nullness flexibility in depth as it's non-determined for now (see KT-35534):
|
||||
* CST(Bar<Foo>, Bar<Foo!>) = Bar<Foo!>
|
||||
* CST(Bar<Foo!>, Bar<Foo>) = Bar<Foo>
|
||||
* But: CST(Foo, Foo!) = CST(Foo!, Foo) = Foo!
|
||||
*/
|
||||
private fun KotlinTypeMarker?.makeFlexibleIfNecessary(c: Context, constraints: List<Constraint>) = with(c) {
|
||||
when (val type = this@makeFlexibleIfNecessary) {
|
||||
is SimpleTypeMarker -> {
|
||||
if (constraints.any { it.type.typeConstructor().isTypeVariable() && it.type.hasFlexibleNullability() }) {
|
||||
createFlexibleType(type.makeSimpleTypeDefinitelyNotNullOrNotNull(), type.withNullability(true))
|
||||
} else type
|
||||
}
|
||||
else -> type
|
||||
}
|
||||
}
|
||||
|
||||
private fun Context.resultType(
|
||||
firstCandidate: KotlinTypeMarker?,
|
||||
secondCandidate: KotlinTypeMarker?,
|
||||
|
||||
Reference in New Issue
Block a user