Don't lose upper non-expected type constraints to include them to intersection type during finding the result type of the fixing type variable

This commit is contained in:
Victor Petukhov
2021-03-11 12:50:42 +03:00
parent b87c2a15b5
commit 91d2f32a57
9 changed files with 72 additions and 8 deletions
@@ -125,6 +125,16 @@ class MutableVariableWithConstraints private constructor(
if (old.position.from is DeclaredUpperBoundConstraintPosition<*> && new.position.from !is DeclaredUpperBoundConstraintPosition<*>)
return false
/*
* We discriminate upper expected type constraints during finding a result type to fix variable (see ResultTypeResolver.kt):
* namely, we don't intersect the expected type with other upper constraints' types to prevent cases like this:
* fun <T : String> materialize(): T = null as T
* val bar: Int = materialize() // T is inferred into String & Int without discriminating upper expected type constraints
* So here we shouldn't lose upper non-expected type constraints.
*/
if (old.position.from is ExpectedTypeConstraintPosition<*> && new.position.from !is ExpectedTypeConstraintPosition<*> && old.kind.isUpper() && new.kind.isUpper())
return false
return when (old.kind) {
ConstraintKind.EQUALITY -> true
ConstraintKind.LOWER -> new.kind.isLower()