[FIR] Implement NULL_FOR_NONNULL_TYPE diagnostics, fix tests

This commit is contained in:
Ivan Kochurkin
2021-04-13 20:17:48 +03:00
parent 9336e4b09b
commit 4353365968
54 changed files with 130 additions and 251 deletions
@@ -30,7 +30,7 @@ fun foo(expr: StringBuilder): Int {
fun unitShort() : Unit = Unit
fun unitShortConv() : Unit = <!RETURN_TYPE_MISMATCH!>1<!>
fun unitShortNull() : Unit = <!RETURN_TYPE_MISMATCH!>null<!>
fun unitShortNull() : Unit = <!NULL_FOR_NONNULL_TYPE!>null<!>
fun intEmpty() : Int {}
fun intShortInfer() = 1
@@ -23,8 +23,8 @@ fun <T> test(x: T) {
baz<Int?, String?>(null, null, ::foo)
baz<Int, String?>(<!ARGUMENT_TYPE_MISMATCH!>null<!>, null, ::foo)
baz<Int?, String>(null, <!ARGUMENT_TYPE_MISMATCH!>null<!>, ::foo)
baz<Int, String?>(<!NULL_FOR_NONNULL_TYPE!>null<!>, null, ::foo)
baz<Int?, String>(null, <!NULL_FOR_NONNULL_TYPE!>null<!>, ::foo)
baz(null, "", ::foo)
baz(1, null, ::foo)
baz(null, null, ::foo)
@@ -13,7 +13,7 @@ fun test2() = run {
inline fun <T, R> Iterable<T>.map(transform: (T) -> R): List<R> = null!!
fun test3(a: List<String>, b: List<Int>) = a.map {
if (it.length == 3) return <!RETURN_TYPE_MISMATCH!>null<!>
if (it.length == 3) return <!NULL_FOR_NONNULL_TYPE!>null<!>
if (it.length == 4) return <!RETURN_TYPE_MISMATCH!>""<!>
if (it.length == 4) return <!RETURN_TYPE_MISMATCH!>5<!>
if (it.length == 4) return b
@@ -4,7 +4,7 @@ fun <T> foo(x: T, y: T!!) = x!!
fun main() {
foo<String>("", "").length
foo<String>("", <!ARGUMENT_TYPE_MISMATCH!>null<!>).length
foo<String>("", <!NULL_FOR_NONNULL_TYPE!>null<!>).length
foo<String?>(null, "").length
foo<String?>(null, null).length
@@ -4,7 +4,7 @@ fun <T> foo(x: T, y: T!!): T!! = x ?: y
fun main() {
foo<String>("", "").length
foo<String>("", <!ARGUMENT_TYPE_MISMATCH!>null<!>).length
foo<String>("", <!NULL_FOR_NONNULL_TYPE!>null<!>).length
foo<String?>(null, "")<!UNSAFE_CALL!>.<!>length
foo<String?>(null, null)<!UNSAFE_CALL!>.<!>length
@@ -1,19 +0,0 @@
// !CHECK_TYPE
interface A {
val foo: Any?
}
interface C: A {
override val foo: String?
}
interface B: A {
override var foo: String
}
fun <T> test(a: T) where T : B, T : C {
a.foo = ""
a.foo = null
a.foo.checkType { _<String>() }
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// !CHECK_TYPE
interface A {
@@ -1,35 +0,0 @@
// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_VARIABLE
fun <E> bar(x: E) {}
fun <T> foo(): T {
val x1: T = <!INITIALIZER_TYPE_MISMATCH!>null<!>
val x2: T? = null
bar<T>(<!ARGUMENT_TYPE_MISMATCH!>null<!>)
bar<T?>(null)
return <!RETURN_TYPE_MISMATCH!>null<!>
}
fun <T> baz(): T? = null
fun <T> foobar(): T = <!RETURN_TYPE_MISMATCH!>null<!>
class A<F> {
fun xyz(x: F) {}
fun foo(): F {
val x1: F = <!INITIALIZER_TYPE_MISMATCH!>null<!>
val x2: F? = null
xyz(<!ARGUMENT_TYPE_MISMATCH!>null<!>)
bar<F?>(null)
return <!RETURN_TYPE_MISMATCH!>null<!>
}
fun baz(): F? = null
fun foobar(): F = <!RETURN_TYPE_MISMATCH!>null<!>
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_VARIABLE
fun <E> bar(x: E) {}
@@ -9,6 +9,6 @@ interface Tr<T> {
fun test(t: Tr<*>) {
t.v = null!!
t.v = ""
t.v = null
t.v = <!NULL_FOR_NONNULL_TYPE!>null<!>
t.v checkType { _<Any?>() }
}
@@ -8,7 +8,7 @@ fun <T> bar(a: T, b: Map<T, String>) = b.get(a)
fun test(a: Int) {
foo(a, null)
bar(a, <!ARGUMENT_TYPE_MISMATCH!>null<!>)
bar(a, <!NULL_FOR_NONNULL_TYPE!>null<!>)
}
fun test1(a: Int) {
foo(a, throw Exception())
@@ -1,23 +0,0 @@
// !CHECK_TYPE
// FILE: A.java
public class A {}
// FILE: X.java
import org.jetbrains.annotations.NotNull;
public class X<T> {
@NotNull T fooN() {return null;}
void barN(@NotNull T a) {}
}
// FILE: Y.java
public class Y extends X<String> {
}
// FILE: test.kt
fun main() {
checkSubtype<Any>(Y().fooN())
Y().barN(<!ARGUMENT_TYPE_MISMATCH!>null<!>);
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// !CHECK_TYPE
// FILE: A.java
public class A {}
@@ -1,23 +0,0 @@
// !CHECK_TYPE
// FILE: A.java
public class A {}
// FILE: X.java
import org.jetbrains.annotations.NotNull;
public class X<T> {
@NotNull T fooN() {return null;}
void barN(@NotNull T a) {}
}
// FILE: Y.java
public class Y extends X<A> {
}
// FILE: test.kt
fun main() {
checkSubtype<Any>(Y().fooN())
Y().barN(<!ARGUMENT_TYPE_MISMATCH!>null<!>);
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// !CHECK_TYPE
// FILE: A.java
public class A {}
@@ -100,7 +100,7 @@ public class SpecializedMap extends AbstractSpecializedMap {
// FILE: main.kt
fun foo(x: SpecializedMap) {
x.containsKey(1)
x.containsKey(<!ARGUMENT_TYPE_MISMATCH!>null<!>)
x.containsKey(<!NULL_FOR_NONNULL_TYPE!>null<!>)
x.<!OVERLOAD_RESOLUTION_AMBIGUITY!>get<!>(2)
x.<!NONE_APPLICABLE!>get<!>(null)
@@ -20,5 +20,5 @@ class In<in F> {
fun test() {
A.foo().x() checkType { _<Any?>() }
A.bar().y(<!ARGUMENT_TYPE_MISMATCH!>null<!>)
A.bar().y(<!NULL_FOR_NONNULL_TYPE!>null<!>)
}
@@ -1,16 +0,0 @@
// FILE: p/J.java
package p;
public class J {
public void _int(int s) {}
}
// FILE: k.kt
import p.*
fun test() {
J()._int(1)
J()._int(<!ARGUMENT_TYPE_MISMATCH!>null<!>)
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// FILE: p/J.java
package p;
@@ -1,26 +0,0 @@
// FILE: A.java
import java.util.*;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class A<T> {
public static A<String> create() {
return null;
}
public void bar(@NotNull T x) {
}
}
// FILE: k.kt
fun test() {
A.create().bar(<!ARGUMENT_TYPE_MISMATCH!>null<!>)
A.create().bar("")
A<String>().bar(<!ARGUMENT_TYPE_MISMATCH!>null<!>)
A<String?>().bar(<!ARGUMENT_TYPE_MISMATCH!>null<!>)
A<String?>().bar("")
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// FILE: A.java
import java.util.*;
@@ -33,9 +33,9 @@ class C2 : A<String?>() {
}
fun test() {
B1().bar(<!ARGUMENT_TYPE_MISMATCH!>null<!>)
B2().bar(<!ARGUMENT_TYPE_MISMATCH!>null<!>)
B1().bar(<!NULL_FOR_NONNULL_TYPE!>null<!>)
B2().bar(<!NULL_FOR_NONNULL_TYPE!>null<!>)
C1().bar(<!ARGUMENT_TYPE_MISMATCH!>null<!>)
C1().bar(<!NULL_FOR_NONNULL_TYPE!>null<!>)
}
@@ -22,6 +22,6 @@ val doubleList: List<Double?> = null!!
fun main() {
Test.rawField.foo("", <!ARGUMENT_TYPE_MISMATCH!>doubleList<!>)
Test.rawField.foo(<!ARGUMENT_TYPE_MISMATCH!>null<!>, <!ARGUMENT_TYPE_MISMATCH!>doubleList<!>)
Test.DerivedRawA().foo(<!ARGUMENT_TYPE_MISMATCH!>null<!>, <!ARGUMENT_TYPE_MISMATCH!>doubleList<!>)
Test.rawField.foo(<!NULL_FOR_NONNULL_TYPE!>null<!>, <!ARGUMENT_TYPE_MISMATCH!>doubleList<!>)
Test.DerivedRawA().foo(<!NULL_FOR_NONNULL_TYPE!>null<!>, <!ARGUMENT_TYPE_MISMATCH!>doubleList<!>)
}
@@ -14,7 +14,7 @@ interface B: A {
fun test(a: A) {
if (a is B && a is C) {
a.foo = ""
a.foo = null
a.foo = <!NULL_FOR_NONNULL_TYPE!>null<!>
a.foo.checkType { _<String>() }
}
@@ -23,8 +23,8 @@ fun foo(k: KotlinClass) {
k.setSomething4("")
k.something4 += ""
k.setSomething4(<!ARGUMENT_TYPE_MISMATCH!>null<!>)
k.something4 = null
k.setSomething4(<!NULL_FOR_NONNULL_TYPE!>null<!>)
k.something4 = <!NULL_FOR_NONNULL_TYPE!>null<!>
useString(k.getSomething5())
useString(k.something5)
@@ -1,13 +0,0 @@
// !WITH_NEW_INFERENCE
// FILE: KotlinFile.kt
fun foo(javaInterface: JavaInterface) {
javaInterface.doIt(<!ARGUMENT_TYPE_MISMATCH!>null<!>) { }
javaInterface.doIt("", <!ARGUMENT_TYPE_MISMATCH!>null<!>)
}
// FILE: JavaInterface.java
import org.jetbrains.annotations.*;
public interface JavaInterface {
void doIt(@NotNull String s, @NotNull Runnable runnable);
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// !WITH_NEW_INFERENCE
// FILE: KotlinFile.kt
fun foo(javaInterface: JavaInterface) {
@@ -32,7 +32,7 @@ abstract class MyIt7 : Iterator<String> {
fun foo(x: Iterator<String>, y: Iterator<String?>) {
x.forEachRemaining(<!ARGUMENT_TYPE_MISMATCH!>null<!>)
x.forEachRemaining(<!NULL_FOR_NONNULL_TYPE!>null<!>)
x.forEachRemaining { it -> it.length }
x.forEachRemaining { it -> it?.length }
@@ -19,7 +19,7 @@ class KotlinMap2 : java.util.AbstractMap<String, Int>() {
fun foo(x: MutableMap<String, Int>, y: java.util.HashMap<String, Int>, z: java.util.AbstractMap<String, Int>) {
x.remove("", 1)
x.remove("", <!ARGUMENT_TYPE_MISMATCH!>""<!>)
x.remove("", <!ARGUMENT_TYPE_MISMATCH!>null<!>)
x.remove("", <!NULL_FOR_NONNULL_TYPE!>null<!>)
y.remove("", 1)
y.remove("", <!ARGUMENT_TYPE_MISMATCH!>""<!>)
@@ -21,7 +21,7 @@ class Pair<X, Y>(val x: X, val y: Y)
typealias PL<T> = Pair<T, List<T>>
typealias PN<T> = Pair<T, Num<T>>
val test5 = PL(1, <!ARGUMENT_TYPE_MISMATCH!>null<!>)
val test5 = PL(1, <!NULL_FOR_NONNULL_TYPE!>null<!>)
class Foo<T>(val p: Pair<T, T>)
@@ -1,24 +0,0 @@
// !WITH_NEW_INFERENCE
// NI_EXPECTED_FILE
object ObjectWithInvoke {
operator fun invoke() = this
}
class ClassWithCompanionObjectWithInvoke {
companion object {
operator fun invoke(x: Any) = x
}
}
typealias WI = ObjectWithInvoke
typealias CWI = ClassWithCompanionObjectWithInvoke
val test1 = WI()
val test2 = WI(<!TOO_MANY_ARGUMENTS!>null<!>)
val test3 = CWI()
val test4 = CWI("")
val test5 = CWI(<!ARGUMENT_TYPE_MISMATCH!>null<!>)
val test5a = ClassWithCompanionObjectWithInvoke(<!ARGUMENT_TYPE_MISMATCH!>null<!>)
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// !WITH_NEW_INFERENCE
// NI_EXPECTED_FILE
@@ -1,24 +0,0 @@
// !USE_EXPERIMENTAL: kotlin.RequiresOptIn
// !DIAGNOSTICS: -UNUSED_VARIABLE
import kotlin.experimental.ExperimentalTypeInference
@OptIn(ExperimentalTypeInference::class)
fun <E> myBuildList(@BuilderInference builderAction: MutableList<E>.() -> Unit) {
ArrayList<E>().builderAction()
}
@OptIn(ExperimentalStdlibApi::class)
fun main() {
val newList1 = myBuildList {
addAll(
listOf(1).map { Foo(<!ARGUMENT_TYPE_MISMATCH!>null<!>) }
)
}
val newList2 = buildList {
addAll(listOf(1,2,3).map{ Foo(<!ARGUMENT_TYPE_MISMATCH!>null<!>) })
}
}
class Foo(val notNullProp: String)
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// !USE_EXPERIMENTAL: kotlin.RequiresOptIn
// !DIAGNOSTICS: -UNUSED_VARIABLE
@@ -7,4 +7,4 @@ fun foo(c : Collection<String>) = {
}
fun bar() : String? = null
fun zoo(s : String) : Boolean = true
fun zoo(s : String) : Boolean = true