Refine subtyping check: pay attention to corresponding supertype nullability

F: Any, T : F? => !isSubtype(T, Any)

It helps to identify upper bounds violation like in KT-7455

 #KT-7455 Fixed
 #KT-2924 Fixed
 #KT-3015 Fixed
This commit is contained in:
Denis Zharkov
2015-08-26 11:22:40 +03:00
parent a906be6dd7
commit 6ecfa6e985
11 changed files with 184 additions and 3 deletions
@@ -0,0 +1,13 @@
// !DIAGNOSTICS: -UNUSED_PARAMETER
interface A<T : CharSequence>
fun <S : CharSequence?> foo1(a: A<<!UPPER_BOUND_VIOLATED!>S<!>>) {}
class B1<E : String?> : A<<!UPPER_BOUND_VIOLATED!>E<!>>
class B2<E : CharSequence?> : A<<!UPPER_BOUND_VIOLATED!>E<!>>
class B3<E> : A<<!UPPER_BOUND_VIOLATED!>E<!>>
class B4<E : CharSequence> : A<E>
fun <X : CharSequence, Y1 : X, Y2: Y1?> foo(a: A<X>, b: A<Y1>, c: A<<!UPPER_BOUND_VIOLATED!>Y2<!>>) {}
@@ -0,0 +1,38 @@
package
internal fun </*0*/ X : kotlin.CharSequence, /*1*/ Y1 : X, /*2*/ Y2 : Y1?> foo(/*0*/ a: A<X>, /*1*/ b: A<Y1>, /*2*/ c: A<Y2>): kotlin.Unit
internal fun </*0*/ S : kotlin.CharSequence?> foo1(/*0*/ a: A<S>): kotlin.Unit
internal interface A</*0*/ T : kotlin.CharSequence> {
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
internal final class B1</*0*/ E : kotlin.String?> : A<E> {
public constructor B1</*0*/ E : kotlin.String?>()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
internal final class B2</*0*/ E : kotlin.CharSequence?> : A<E> {
public constructor B2</*0*/ E : kotlin.CharSequence?>()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
internal final class B3</*0*/ E> : A<E> {
public constructor B3</*0*/ E>()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
internal final class B4</*0*/ E : kotlin.CharSequence> : A<E> {
public constructor B4</*0*/ E : kotlin.CharSequence>()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
@@ -0,0 +1,18 @@
// !DIAGNOSTICS: -UNUSED_PARAMETER
class A<T : CharSequence>(x: T)
fun <E : CharSequence> foo1(x: E) {}
fun <E : CharSequence> E.foo2() {}
fun <F : String?> bar(x: F) {
<!TYPE_INFERENCE_UPPER_BOUND_VIOLATED!>A<!>(x)
A<<!UPPER_BOUND_VIOLATED!>F<!>>(x)
<!TYPE_INFERENCE_UPPER_BOUND_VIOLATED!>foo1<!>(x)
foo1<<!UPPER_BOUND_VIOLATED!>F<!>>(x)
x.<!TYPE_INFERENCE_UPPER_BOUND_VIOLATED!>foo2<!>()
x.foo2<<!UPPER_BOUND_VIOLATED!>F<!>>()
}
@@ -0,0 +1,12 @@
package
internal fun </*0*/ F : kotlin.String?> bar(/*0*/ x: F): kotlin.Unit
internal fun </*0*/ E : kotlin.CharSequence> foo1(/*0*/ x: E): kotlin.Unit
internal fun </*0*/ E : kotlin.CharSequence> E.foo2(): kotlin.Unit
internal final class A</*0*/ T : kotlin.CharSequence> {
public constructor A</*0*/ T : kotlin.CharSequence>(/*0*/ x: T)
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
@@ -0,0 +1,31 @@
// !DIAGNOSTICS: -UNUSED_PARAMETER, -BASE_WITH_NULLABLE_UPPER_BOUND
class A<F> {
fun <E : F> foo1(x: E) {}
fun <E : F?> foo2(x: E) {}
fun <Z : F, W : Z?> bar(x: F, y: F?, z: Z, w: W) {
foo1<F>(x)
foo1(x)
foo2<F>(x)
foo2(x)
foo1<<!UPPER_BOUND_VIOLATED!>F?<!>>(y)
<!TYPE_INFERENCE_UPPER_BOUND_VIOLATED!>foo1<!>(y)
foo2<F?>(y)
foo2(y)
foo1<F>(<!TYPE_MISMATCH!>y<!>)
foo2<F>(<!TYPE_MISMATCH!>y<!>)
foo1<Z>(z)
foo1(z)
foo2<Z>(z)
foo2(z)
foo1<<!UPPER_BOUND_VIOLATED!>W<!>>(w)
<!TYPE_INFERENCE_UPPER_BOUND_VIOLATED!>foo1<!>(w)
foo2<W>(w)
foo2(w)
foo1<<!UPPER_BOUND_VIOLATED!>W<!>>(w)
}
}
@@ -0,0 +1,11 @@
package
internal final class A</*0*/ F> {
public constructor A</*0*/ F>()
internal final fun </*0*/ Z : F, /*1*/ W : Z?> bar(/*0*/ x: F, /*1*/ y: F?, /*2*/ z: Z, /*3*/ w: W): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
internal final fun </*0*/ E : F> foo1(/*0*/ x: E): kotlin.Unit
internal final fun </*0*/ E : F?> foo2(/*0*/ x: E): kotlin.Unit
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
@@ -0,0 +1,17 @@
// !DIAGNOSTICS: -UNUSED_PARAMETER,-UNUSED_VARIABLE
fun <T : CharSequence?> bar1(x: T) {}
fun bar2(x: CharSequence?) {}
fun <T : CharSequence> bar3(x: T) {}
fun bar4(x: String) {}
fun <T : String?> foo(x: T) {
bar1(x)
bar2(x)
<!TYPE_INFERENCE_UPPER_BOUND_VIOLATED!>bar3<!>(x)
bar4(<!TYPE_MISMATCH!>x<!>)
}
@@ -0,0 +1,7 @@
package
internal fun </*0*/ T : kotlin.CharSequence?> bar1(/*0*/ x: T): kotlin.Unit
internal fun bar2(/*0*/ x: kotlin.CharSequence?): kotlin.Unit
internal fun </*0*/ T : kotlin.CharSequence> bar3(/*0*/ x: T): kotlin.Unit
internal fun bar4(/*0*/ x: kotlin.String): kotlin.Unit
internal fun </*0*/ T : kotlin.String?> foo(/*0*/ x: T): kotlin.Unit