Type intersection fix: T & (final A) is no more calculated as just A #KT-7801 Fixed

This commit is contained in:
Mikhail Glukhikh
2016-01-21 15:41:45 +03:00
parent 3106a8508a
commit b3c5760eb5
2 changed files with 15 additions and 9 deletions
@@ -78,21 +78,27 @@ public class TypeIntersector {
outer:
for (KotlinType type : nullabilityStripped) {
if (!TypeUtils.canHaveSubtypes(typeChecker, type)) {
boolean relativeToAll = true;
for (KotlinType other : nullabilityStripped) {
// It makes sense to check for subtyping (other <: type), despite that
// type is not supposed to be open, for there're enums
if (!TypeUnifier.mayBeEqual(type, other) && !typeChecker.isSubtypeOf(type, other) && !typeChecker.isSubtypeOf(other, type)) {
boolean mayBeEqual = TypeUnifier.mayBeEqual(type, other);
boolean relative = typeChecker.isSubtypeOf(type, other) || typeChecker.isSubtypeOf(other, type);
if (!mayBeEqual && !relative) {
return null;
}
}
return TypeUtils.makeNullableAsSpecified(type, allNullable);
}
else {
for (KotlinType other : nullabilityStripped) {
if (!type.equals(other) && typeChecker.isSubtypeOf(other, type)) {
continue outer;
else if (!relative) {
// To build T & (final A), instead of returning just A as intersection
relativeToAll = false;
break;
}
}
if (relativeToAll) return TypeUtils.makeNullableAsSpecified(type, allNullable);
}
for (KotlinType other : nullabilityStripped) {
if (!type.equals(other) && typeChecker.isSubtypeOf(other, type)) {
continue outer;
}
}
// Don't add type if it is already present, to avoid trivial type intersections in result
@@ -29,7 +29,7 @@ fun <T : CharSequence?> foo(x: T) {
<!DEBUG_INFO_SMARTCAST!>x<!>.length
x<!UNNECESSARY_SAFE_CALL!>?.<!>length
<!DEBUG_INFO_SMARTCAST!>x<!>.bar1()
x.bar1()
x.bar2()
<!DEBUG_INFO_SMARTCAST!>x<!>.bar3()
}