NI: introduce warning about implicitly inferred Nothing with existing non-Nothing expected type

^KT-35406 Fixed
This commit is contained in:
Victor Petukhov
2020-02-13 16:09:50 +03:00
parent e3184e407d
commit 51edf2b351
18 changed files with 414 additions and 42 deletions
@@ -30,7 +30,7 @@ fun <T> test(x: T) {
<!REIFIED_TYPE_FORBIDDEN_SUBSTITUTION, REIFIED_TYPE_FORBIDDEN_SUBSTITUTION!>baz<!>(null, null, ::foo)
val s3: Pair<Int, String?> = <!NI;TYPE_MISMATCH, OI;TYPE_INFERENCE_EXPECTED_TYPE_MISMATCH!>bar(null, null, ::<!OI;TYPE_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>foo<!>)<!>
val s4: Pair<Int?, String> = <!NI;TYPE_MISMATCH, NI;TYPE_MISMATCH, NI;TYPE_MISMATCH, OI;TYPE_INFERENCE_EXPECTED_TYPE_MISMATCH!>bar(null, null, ::<!NI;IMPLICIT_NOTHING_AS_TYPE_PARAMETER, OI;TYPE_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>foo<!>)<!>
val s4: Pair<Int?, String> = <!NI;TYPE_MISMATCH, NI;TYPE_MISMATCH, NI;TYPE_MISMATCH, OI;TYPE_INFERENCE_EXPECTED_TYPE_MISMATCH!>bar(null, null, ::<!NI;IMPLICIT_NOTHING_TYPE_ARGUMENT_IN_RETURN_POSITION, OI;TYPE_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>foo<!>)<!>
val s5: Pair<Int, String> = <!NI;TYPE_MISMATCH, NI;TYPE_MISMATCH, OI;TYPE_INFERENCE_EXPECTED_TYPE_MISMATCH!>bar(1, "", ::foo)<!>
val (a1: Int, b1: String) = <!COMPONENT_FUNCTION_RETURN_TYPE_MISMATCH!>bar(1, "", ::foo)<!>
@@ -13,7 +13,7 @@ fun <E4, F : E4> noSmartCast4(arg: E4?, fn: F): E4 = TODO()
fun testSmartCast(s: String?) {
id(
if (s != null) ""
else <!IMPLICIT_NOTHING_AS_TYPE_PARAMETER!>smartCast<!>(null) { "" }
else <!IMPLICIT_NOTHING_TYPE_ARGUMENT_IN_RETURN_POSITION!>smartCast<!>(null) { "" }
)
<!DEBUG_INFO_SMARTCAST!>s<!>.length
}
@@ -46,7 +46,7 @@ fun testNoSmartCast3(s: String?) {
fun testNoSmartCast4(s: String?) {
id(
if (s != null) ( {""} )
else <!IMPLICIT_NOTHING_AS_TYPE_PARAMETER, IMPLICIT_NOTHING_AS_TYPE_PARAMETER!>noSmartCast4<!>(null) <!TYPE_MISMATCH!>{ <!TYPE_MISMATCH!>""<!> }<!>
else <!IMPLICIT_NOTHING_TYPE_ARGUMENT_IN_RETURN_POSITION!>noSmartCast4<!>(null) <!TYPE_MISMATCH!>{ <!TYPE_MISMATCH!>""<!> }<!>
)
s<!UNSAFE_CALL!>.<!>length
}
@@ -9,5 +9,5 @@ fun <K> invOut(y: K?): Inv<Out<K>> = TODO()
fun <R> test(x: Inv<Out<R>>): R = TODO()
fun testNothing() {
<!IMPLICIT_NOTHING_AS_TYPE_PARAMETER!>test<!>(invOut(null)) checkType { _<Nothing>() }
<!IMPLICIT_NOTHING_TYPE_ARGUMENT_IN_RETURN_POSITION!>test<!>(invOut(null)) checkType { _<Nothing>() }
}
@@ -14,7 +14,7 @@ inline fun <reified M> materializeReifiedUnbound(): M = TODO()
fun <T> select(a: T, b: T): T = TODO()
fun test1() {
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Nothing")!><!IMPLICIT_NOTHING_AS_TYPE_PARAMETER!>take<!>(null)<!>
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Nothing")!><!IMPLICIT_NOTHING_TYPE_ARGUMENT_IN_RETURN_POSITION!>take<!>(null)<!>
}
fun test2() {
@@ -22,20 +22,20 @@ fun test2() {
}
fun test3() {
<!IMPLICIT_NOTHING_AS_TYPE_PARAMETER, REIFIED_TYPE_FORBIDDEN_SUBSTITUTION!>takeReifiedUnbound<!>(null)
<!IMPLICIT_NOTHING_TYPE_ARGUMENT_IN_RETURN_POSITION, REIFIED_TYPE_FORBIDDEN_SUBSTITUTION!>takeReifiedUnbound<!>(null)
}
fun test4(): Bound = <!DEBUG_INFO_EXPRESSION_TYPE("Bound")!>takeReifiedUnbound(null)<!>
fun test5(): Bound? = select(
null,
<!IMPLICIT_NOTHING_AS_TYPE_PARAMETER, IMPLICIT_NOTHING_AS_TYPE_PARAMETER!>materialize<!>()
<!IMPLICIT_NOTHING_TYPE_ARGUMENT_IN_RETURN_POSITION!>materialize<!>()
)
fun test6() {
select(
null,
<!IMPLICIT_NOTHING_AS_TYPE_PARAMETER, IMPLICIT_NOTHING_AS_TYPE_PARAMETER, REIFIED_TYPE_FORBIDDEN_SUBSTITUTION, REIFIED_TYPE_FORBIDDEN_SUBSTITUTION!>materializeReified<!>()
<!IMPLICIT_NOTHING_TYPE_ARGUMENT_IN_RETURN_POSITION, REIFIED_TYPE_FORBIDDEN_SUBSTITUTION, REIFIED_TYPE_FORBIDDEN_SUBSTITUTION!>materializeReified<!>()
)
}
@@ -0,0 +1,105 @@
// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_VARIABLE -UNCHECKED_CAST -UNUSED_EXPRESSION -UNREACHABLE_CODE
// !LANGUAGE: +NewInference
fun <K> materialize(): K = null as K
fun <K, T> materializeWithGenericArg(x: T): K = null as K
fun <K> id(x: K): K = null as K
fun <K> K.idFromReceiver(): K = null as K
fun <K> K.idFromReceiverWithArg(x: String): K = null as K
fun <S> select(x: S, y: S): S = x
class Foo<T> {
fun idFromClassTypeArg(): T = null as T
fun <K> idFromClassTypeArgWithAnotherTypeArg(): T = null as T
fun <K> materialize(): K = null as K
}
fun test() {
if (true) materialize() else null
val x1: String? = if (true) materialize() else null
val x2: String? = if (true) materializeWithGenericArg("") else null
val x3: String? = if (true) {
if (true) materialize() else null
} else null
val x4: String? = if (true) {
select(materialize(), null)
} else null
val x5: String? = select(if (true) materialize() else null, null)
val x6: String? = select(materialize(), null)
val x7: String? = select(null.idFromReceiver(), null)
val x8: String? = select(null.idFromReceiverWithArg(""), null)
val foo = Foo<Nothing?>()
val x9: String? = select(foo.materialize(), null)
val x10: String? = select(foo.idFromClassTypeArgWithAnotherTypeArg(), null)
val x11: String? = select(foo.idFromClassTypeArg(), null)
foo.run {
val x12: String? = select(materialize(), null)
val x13: String? = select(idFromClassTypeArgWithAnotherTypeArg(), null)
val x14: String? = select(idFromClassTypeArg(), null)
}
val boolean: Boolean? = true
val x15: String? = when (boolean) {
true -> select(materialize(), null)
false -> select(materialize(), null)
null -> null
}
val x16: String? = when (boolean) {
true -> null
false -> materialize()
null -> null
}
val x17: String? = when (boolean) {
true -> if (true) null else materialize()
false -> if (true) materialize() else null
null -> if (true) null else null
}
val x18: String? = try {
materialize()
} catch (e: Exception) {
null
}
val x19: String? = if (true) materialize<Nothing?>() else null
val x20: String? = if (true) materialize<String?>() else null
val x21: String? = if (true) materialize() else TODO()
val x22: String? = if (true) return else materialize()
val x23: String? = if (true) id(null) else null
foo1(if (true) materialize() else null)
val x24 = id(foo1(if (true) materialize() else null))
val x25 = select(materialize(), null).foo2()
// TODO
val x26 = select(materialize(), null).run { foo2() }
val x27: () -> String? = {
id(id(if (true) materialize() else null))
}
}
fun foo1(x: String?) {}
fun String?.foo2() {}
@@ -0,0 +1,105 @@
// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_VARIABLE -UNCHECKED_CAST -UNUSED_EXPRESSION -UNREACHABLE_CODE
// !LANGUAGE: +NewInference
fun <K> materialize(): K = null as K
fun <K, T> materializeWithGenericArg(x: T): K = null as K
fun <K> id(x: K): K = null as K
fun <K> K.idFromReceiver(): K = null as K
fun <K> K.idFromReceiverWithArg(x: String): K = null as K
fun <S> select(x: S, y: S): S = x
class Foo<T> {
fun idFromClassTypeArg(): T = null as T
fun <K> idFromClassTypeArgWithAnotherTypeArg(): T = null as T
fun <K> materialize(): K = null as K
}
fun test() {
if (true) materialize() else null
val x1: String? = if (true) <!IMPLICIT_NOTHING_TYPE_ARGUMENT_AGAINST_NOT_NOTHING_EXPECTED_TYPE!>materialize<!>() else null
val x2: String? = if (true) <!IMPLICIT_NOTHING_TYPE_ARGUMENT_AGAINST_NOT_NOTHING_EXPECTED_TYPE!>materializeWithGenericArg<!>("") else null
val x3: String? = if (true) {
if (true) <!IMPLICIT_NOTHING_TYPE_ARGUMENT_AGAINST_NOT_NOTHING_EXPECTED_TYPE!>materialize<!>() else null
} else null
val x4: String? = if (true) {
select(<!IMPLICIT_NOTHING_TYPE_ARGUMENT_AGAINST_NOT_NOTHING_EXPECTED_TYPE!>materialize<!>(), null)
} else null
val x5: String? = select(if (true) <!IMPLICIT_NOTHING_TYPE_ARGUMENT_AGAINST_NOT_NOTHING_EXPECTED_TYPE!>materialize<!>() else null, null)
val x6: String? = select(<!IMPLICIT_NOTHING_TYPE_ARGUMENT_AGAINST_NOT_NOTHING_EXPECTED_TYPE!>materialize<!>(), null)
val x7: String? = select(null.<!IMPLICIT_NOTHING_TYPE_ARGUMENT_AGAINST_NOT_NOTHING_EXPECTED_TYPE!>idFromReceiver<!>(), null)
val x8: String? = select(null.<!IMPLICIT_NOTHING_TYPE_ARGUMENT_AGAINST_NOT_NOTHING_EXPECTED_TYPE!>idFromReceiverWithArg<!>(""), null)
val foo = Foo<Nothing?>()
val x9: String? = select(foo.<!IMPLICIT_NOTHING_TYPE_ARGUMENT_AGAINST_NOT_NOTHING_EXPECTED_TYPE!>materialize<!>(), null)
val x10: String? = select(foo.<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>idFromClassTypeArgWithAnotherTypeArg<!>(), null)
val x11: String? = select(foo.idFromClassTypeArg(), null)
foo.run {
val x12: String? = select(<!IMPLICIT_NOTHING_TYPE_ARGUMENT_AGAINST_NOT_NOTHING_EXPECTED_TYPE!>materialize<!>(), null)
val x13: String? = select(<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>idFromClassTypeArgWithAnotherTypeArg<!>(), null)
val x14: String? = select(idFromClassTypeArg(), null)
}
val boolean: Boolean? = true
val x15: String? = when (boolean) {
true -> select(<!IMPLICIT_NOTHING_TYPE_ARGUMENT_AGAINST_NOT_NOTHING_EXPECTED_TYPE!>materialize<!>(), null)
false -> select(<!IMPLICIT_NOTHING_TYPE_ARGUMENT_AGAINST_NOT_NOTHING_EXPECTED_TYPE!>materialize<!>(), null)
null -> null
}
val x16: String? = when (boolean) {
true -> null
false -> <!IMPLICIT_NOTHING_TYPE_ARGUMENT_AGAINST_NOT_NOTHING_EXPECTED_TYPE!>materialize<!>()
null -> null
}
val x17: String? = when (boolean) {
true -> if (true) null else <!IMPLICIT_NOTHING_TYPE_ARGUMENT_AGAINST_NOT_NOTHING_EXPECTED_TYPE!>materialize<!>()
false -> if (true) <!IMPLICIT_NOTHING_TYPE_ARGUMENT_AGAINST_NOT_NOTHING_EXPECTED_TYPE!>materialize<!>() else null
null -> if (true) null else null
}
val x18: String? = try {
<!IMPLICIT_NOTHING_TYPE_ARGUMENT_AGAINST_NOT_NOTHING_EXPECTED_TYPE!>materialize<!>()
} catch (e: Exception) {
null
}
val x19: String? = if (true) materialize<Nothing?>() else null
val x20: String? = if (true) materialize<String?>() else null
val x21: String? = if (true) <!IMPLICIT_NOTHING_TYPE_ARGUMENT_IN_RETURN_POSITION!>materialize<!>() else TODO()
val x22: String? = if (true) return else <!IMPLICIT_NOTHING_TYPE_ARGUMENT_IN_RETURN_POSITION!>materialize<!>()
val x23: String? = if (true) <!IMPLICIT_NOTHING_TYPE_ARGUMENT_AGAINST_NOT_NOTHING_EXPECTED_TYPE!>id<!>(null) else null
foo1(if (true) <!IMPLICIT_NOTHING_TYPE_ARGUMENT_AGAINST_NOT_NOTHING_EXPECTED_TYPE!>materialize<!>() else null)
val x24 = id(foo1(if (true) <!IMPLICIT_NOTHING_TYPE_ARGUMENT_AGAINST_NOT_NOTHING_EXPECTED_TYPE!>materialize<!>() else null))
val x25 = select(<!IMPLICIT_NOTHING_TYPE_ARGUMENT_AGAINST_NOT_NOTHING_EXPECTED_TYPE!>materialize<!>(), null).foo2()
// TODO
val x26 = select(materialize(), null).run { foo2() }
val x27: () -> String? = {
id(id(if (true) <!IMPLICIT_NOTHING_TYPE_ARGUMENT_AGAINST_NOT_NOTHING_EXPECTED_TYPE!>materialize<!>() else null))
}
}
fun foo1(x: String?) {}
fun String?.foo2() {}
@@ -0,0 +1,21 @@
package
public fun foo1(/*0*/ x: kotlin.String?): kotlin.Unit
public fun </*0*/ K> id(/*0*/ x: K): K
public fun </*0*/ K> materialize(): K
public fun </*0*/ K, /*1*/ T> materializeWithGenericArg(/*0*/ x: T): K
public fun </*0*/ S> select(/*0*/ x: S, /*1*/ y: S): S
public fun test(): kotlin.Unit
public fun kotlin.String?.foo2(): kotlin.Unit
public fun </*0*/ K> K.idFromReceiver(): K
public fun </*0*/ K> K.idFromReceiverWithArg(/*0*/ x: kotlin.String): K
public final class Foo</*0*/ T> {
public constructor Foo</*0*/ 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 final fun idFromClassTypeArg(): T
public final fun </*0*/ K> idFromClassTypeArgWithAnotherTypeArg(): T
public final fun </*0*/ K> materialize(): K
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
@@ -40,7 +40,7 @@ class Context<T>
fun <T> Any.decodeIn(typeFrom: Context<in T>): T = something()
fun <T> Any?.decodeOut1(typeFrom: Context<out T>): T {
return <!NI;TYPE_MISMATCH!>this?.<!IMPLICIT_NOTHING_AS_TYPE_PARAMETER, NI;IMPLICIT_NOTHING_AS_TYPE_PARAMETER!>decodeIn<!>(typeFrom) ?: <!OI;TYPE_MISMATCH!>kotlin.Unit<!><!>
return <!NI;TYPE_MISMATCH!>this?.<!IMPLICIT_NOTHING_TYPE_ARGUMENT_IN_RETURN_POSITION!>decodeIn<!>(typeFrom) ?: <!OI;TYPE_MISMATCH!>kotlin.Unit<!><!>
}
fun <T> Any.decodeOut2(typeFrom: Context<out T>): T {
@@ -48,11 +48,11 @@ fun <T> Any.decodeOut2(typeFrom: Context<out T>): T {
}
fun <T> Any.decodeOut3(typeFrom: Context<out T>): T {
<!UNREACHABLE_CODE!>val x =<!> this.<!IMPLICIT_NOTHING_AS_TYPE_PARAMETER!>decodeIn<!>(typeFrom)
<!UNREACHABLE_CODE!>val x =<!> this.<!IMPLICIT_NOTHING_TYPE_ARGUMENT_IN_RETURN_POSITION!>decodeIn<!>(typeFrom)
}
fun <T> Any.decodeOut4(typeFrom: Context<out T>): T {
<!UNREACHABLE_CODE!>val x: Any =<!> this.<!IMPLICIT_NOTHING_AS_TYPE_PARAMETER!>decodeIn<!>(typeFrom)
<!UNREACHABLE_CODE!>val x: Any =<!> this.<!IMPLICIT_NOTHING_TYPE_ARGUMENT_IN_RETURN_POSITION!>decodeIn<!>(typeFrom)
}
class TrieNode<out E> {
@@ -91,7 +91,7 @@ interface Worker<out T>
interface RenderContext<StateT, in OutputT : Any>
val emptyOrNull: List<Nothing>? = null
val x = emptyOrNull?.<!IMPLICIT_NOTHING_AS_TYPE_PARAMETER!>get<!>(0)
val x = emptyOrNull?.<!IMPLICIT_NOTHING_TYPE_ARGUMENT_IN_RETURN_POSITION!>get<!>(0)
val errorCompletion = { <!UNUSED_ANONYMOUS_PARAMETER!>e<!>: Throwable -> throw Exception() }
@@ -18,6 +18,6 @@ private object Scope {
fun <T> materialize(): T = Any() as T
fun test(i: Inv<out Number>) {
val <!UNUSED_VARIABLE!>p<!>: Int by <!IMPLICIT_NOTHING_AS_TYPE_PARAMETER!>Scope.Delegate(i)<!>
val <!UNUSED_VARIABLE!>p<!>: Int by <!IMPLICIT_NOTHING_TYPE_ARGUMENT_IN_RETURN_POSITION!>Scope.Delegate(i)<!>
}
}