FIR checker: warn unnecessary non-null assertions

This commit is contained in:
Jinseong Jeon
2021-04-01 11:44:47 -07:00
committed by Mikhail Glukhikh
parent 5229d4e4f4
commit 2ecb6733ed
72 changed files with 268 additions and 246 deletions
@@ -17,7 +17,7 @@ fun test() {
else -> ::baz
})
val x5: (Int) -> Int = bar(::baz!!)
val x5: (Int) -> Int = bar(::baz<!NOT_NULL_ASSERTION_ON_CALLABLE_REFERENCE!>!!<!>)
(if (true) ::baz else ::baz)(1)
}
@@ -10,18 +10,18 @@ fun main() {
val x4 = <!UNRESOLVED_REFERENCE!>logger<!>?::info?::<!UNRESOLVED_REFERENCE!>print<!>?::<!UNRESOLVED_REFERENCE!>print<!>?::<!UNRESOLVED_REFERENCE!>print<!>?::<!UNRESOLVED_REFERENCE!>print<!>?::<!UNRESOLVED_REFERENCE!>print<!>?::<!UNRESOLVED_REFERENCE!>print<!>?::<!UNRESOLVED_REFERENCE!>print<!>?::<!UNRESOLVED_REFERENCE!>print<!>?::<!UNRESOLVED_REFERENCE!>print<!>?::<!UNRESOLVED_REFERENCE!>print<!>
val x5 = <!UNRESOLVED_REFERENCE!>logger<!>::info?::<!UNRESOLVED_REFERENCE!>print<!>?::<!UNRESOLVED_REFERENCE!>print<!>?::<!UNRESOLVED_REFERENCE!>print<!>?::<!UNRESOLVED_REFERENCE!>print<!>?::<!UNRESOLVED_REFERENCE!>print<!>?::<!UNRESOLVED_REFERENCE!>print<!>?::<!UNRESOLVED_REFERENCE!>print<!>?::<!UNRESOLVED_REFERENCE!>print<!>?::<!UNRESOLVED_REFERENCE!>print<!>?::<!UNRESOLVED_REFERENCE!>print<!>
val x6 = <!UNRESOLVED_REFERENCE!>logger<!>!!::<!UNRESOLVED_REFERENCE!>info<!>?::<!UNRESOLVED_REFERENCE!>print<!>?::<!UNRESOLVED_REFERENCE!>print<!>
val x7 = <!UNRESOLVED_REFERENCE!>logger<!>::info!!::<!UNRESOLVED_REFERENCE!>print<!>?::<!UNRESOLVED_REFERENCE!>print<!>
val x8 = <!UNRESOLVED_REFERENCE!>logger<!>?::info!!::<!UNRESOLVED_REFERENCE!>print<!>?::<!UNRESOLVED_REFERENCE!>print<!>
val x7 = <!UNRESOLVED_REFERENCE!>logger<!>::info<!NOT_NULL_ASSERTION_ON_CALLABLE_REFERENCE!>!!<!>::<!UNRESOLVED_REFERENCE!>print<!>?::<!UNRESOLVED_REFERENCE!>print<!>
val x8 = <!UNRESOLVED_REFERENCE!>logger<!>?::info<!NOT_NULL_ASSERTION_ON_CALLABLE_REFERENCE!>!!<!>::<!UNRESOLVED_REFERENCE!>print<!>?::<!UNRESOLVED_REFERENCE!>print<!>
val x9 = <!UNRESOLVED_REFERENCE!>logger<!>!!::<!UNRESOLVED_REFERENCE!>info<!>?::<!UNRESOLVED_REFERENCE!>print<!>?::<!UNRESOLVED_REFERENCE!>print<!>
val x10 = <!UNRESOLVED_REFERENCE!>logger<!>::info?::print!!::<!UNRESOLVED_REFERENCE!>print<!>
val x11 = <!UNRESOLVED_REFERENCE!>logger<!>!!::info!!::print!!::<!UNRESOLVED_REFERENCE!>print<!>
val x12 = <!UNRESOLVED_REFERENCE!>logger<!>?::info!!::print!!::<!UNRESOLVED_REFERENCE!>print<!>
val x10 = <!UNRESOLVED_REFERENCE!>logger<!>::info?::print<!NOT_NULL_ASSERTION_ON_CALLABLE_REFERENCE!>!!<!>::<!UNRESOLVED_REFERENCE!>print<!>
val x11 = <!UNRESOLVED_REFERENCE!>logger<!>!!::info<!NOT_NULL_ASSERTION_ON_CALLABLE_REFERENCE!>!!<!>::print<!NOT_NULL_ASSERTION_ON_CALLABLE_REFERENCE!>!!<!>::<!UNRESOLVED_REFERENCE!>print<!>
val x12 = <!UNRESOLVED_REFERENCE!>logger<!>?::info<!NOT_NULL_ASSERTION_ON_CALLABLE_REFERENCE!>!!<!>::print<!NOT_NULL_ASSERTION_ON_CALLABLE_REFERENCE!>!!<!>::<!UNRESOLVED_REFERENCE!>print<!>
val x13 = 42?::<!UNRESOLVED_REFERENCE!>unresolved<!>?::<!UNRESOLVED_REFERENCE!>print<!>
val x14 = <!UNRESOLVED_REFERENCE!>logger<!><!SYNTAX!>?!!::info?::print?::print<!>
val x15 = <!UNRESOLVED_REFERENCE!>logger<!>::info<!SYNTAX!>?!!::print?::print<!>
val x16 = <!UNRESOLVED_REFERENCE!>logger<!>!!?::<!UNRESOLVED_REFERENCE!>info<!>?::<!UNRESOLVED_REFERENCE!>print<!>?::<!UNRESOLVED_REFERENCE!>print<!>
val x17 = <!UNRESOLVED_REFERENCE!>logger<!>::info!!?::<!UNRESOLVED_REFERENCE!>print<!>?::<!UNRESOLVED_REFERENCE!>print<!>
val x17 = <!UNRESOLVED_REFERENCE!>logger<!>::info<!NOT_NULL_ASSERTION_ON_CALLABLE_REFERENCE!>!!<!>?::<!UNRESOLVED_REFERENCE!>print<!>?::<!UNRESOLVED_REFERENCE!>print<!>
// It must be OK
val x18 = String?::hashCode ?: ::foo
@@ -2,7 +2,7 @@
fun testCompound() {
operator fun Nothing.get(i: Int) {}
todo()!![12]
todo()<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>[12]
}
fun testCompound1() {
@@ -10,4 +10,4 @@ fun testCompound1() {
(todo() * "")[1]
}
fun todo(): Nothing = throw Exception()
fun todo(): Nothing = throw Exception()
@@ -9,7 +9,7 @@ fun testPostfixWithCall(n: Nothing) {
}
fun testPostfixSpecial() {
todo()!!
todo()<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>
}
fun todo(): Nothing = throw Exception()
fun todo(): Nothing = throw Exception()
@@ -4,8 +4,8 @@
fun use(a: Any?) = a
fun test() {
{ }!!
use({ }!!);
{ }<!NOT_NULL_ASSERTION_ON_LAMBDA_EXPRESSION!>!!<!>
use({ }<!NOT_NULL_ASSERTION_ON_LAMBDA_EXPRESSION!>!!<!>);
// KT-KT-9070
{ } ?: 1
@@ -6,7 +6,7 @@ interface G {
}
fun foo1(a: Int?, b: G) {
b[a!!, a!!] = a
b[a!!, a<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>] = a
checkSubtype<Int>(a)
}
@@ -1,7 +1,7 @@
// !CHECK_TYPE
fun foo1(a: Int?, b: Array<Array<Int>>) {
b[a!!][a!!] = a
b[a!!][a<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>] = a
checkSubtype<Int>(a)
}
@@ -2,7 +2,7 @@ fun bar(x: Int) = x + 1
fun f1(x: Int?) {
<!INAPPLICABLE_CANDIDATE!>bar<!>(x)
if (x != null) bar(x!!)
if (x != null) bar(x<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>)
if (x == null) bar(x!!)
}
@@ -11,13 +11,13 @@ fun f2(x: Int?) {
}
fun f3(x: Int?) {
if (x != null) bar(x!!) else x!!
if (x != null) bar(x<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>) else x!!
}
fun f4(x: Int?) {
if (x == null) x!! else bar(x!!)
if (x == null) x!! else bar(x<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>)
}
fun f5(x: Int?) {
if (x == null) else bar(x!!)
if (x == null) else bar(x<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>)
}
@@ -26,5 +26,5 @@ fun foo() {
if (z != null) bar(z)
<!INAPPLICABLE_CANDIDATE!>bar<!>(z)
bar(z!!)
if (z != null) bar(z!!)
if (z != null) bar(z<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>)
}
@@ -11,6 +11,6 @@ fun <T> foo(b: B, f: () -> T): T = f()
fun test(c: C) {
<!OVERLOAD_RESOLUTION_AMBIGUITY!>foo<!>(c) f@ {
c!!
c<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>
}
}
@@ -388,49 +388,49 @@ fun poll66(): Flow<String> {
fun poll7(): Flow<String> {
return flow {
val inv = ::bar!!
val inv = ::bar<!NOT_NULL_ASSERTION_ON_CALLABLE_REFERENCE!>!!<!>
inv(<!NO_VALUE_FOR_PARAMETER!>)<!>
}
}
fun poll71(): Flow<String> {
return flow {
val inv = ::bar2!!
val inv = ::bar2<!NOT_NULL_ASSERTION_ON_CALLABLE_REFERENCE!>!!<!>
inv()
}
}
fun poll72(): Flow<String> {
return flow {
val inv = ::bar3!!
val inv = ::bar3<!NOT_NULL_ASSERTION_ON_CALLABLE_REFERENCE!>!!<!>
inv()
}
}
fun poll73(): Flow<String> {
return flow {
val inv = ::bar4!!
val inv = ::bar4<!NOT_NULL_ASSERTION_ON_CALLABLE_REFERENCE!>!!<!>
inv
}
}
fun poll74(): Flow<String> {
return flow {
val inv = ::bar5!!
val inv = ::bar5<!NOT_NULL_ASSERTION_ON_CALLABLE_REFERENCE!>!!<!>
inv
}
}
fun poll75(): Flow<String> {
return flow {
val inv = ::Foo6!!
val inv = ::Foo6<!NOT_NULL_ASSERTION_ON_CALLABLE_REFERENCE!>!!<!>
inv
}
}
fun poll76(): Flow<String> {
return flow {
val inv = ::Foo7!!
val inv = ::Foo7<!NOT_NULL_ASSERTION_ON_CALLABLE_REFERENCE!>!!<!>
inv
}
}
@@ -36,21 +36,21 @@ class Flow<out R>(private val block: suspend FlowCollector<R>.() -> Unit)
fun poll71(): Flow<String> {
return flow {
val inv = ::bar2!!
val inv = ::bar2<!NOT_NULL_ASSERTION_ON_CALLABLE_REFERENCE!>!!<!>
inv()
}
}
fun poll73(): Flow<String> {
return flow {
val inv = ::bar4!!
val inv = ::bar4<!NOT_NULL_ASSERTION_ON_CALLABLE_REFERENCE!>!!<!>
inv
}
}
fun poll75(): Flow<String> {
return flow {
val inv = ::Foo6!!
val inv = ::Foo6<!NOT_NULL_ASSERTION_ON_CALLABLE_REFERENCE!>!!<!>
inv
}
}
@@ -37,49 +37,49 @@ class Flow<out R>(private val block: suspend FlowCollector<R>.() -> Unit)
fun poll7(): Flow<String> {
return flow {
val inv = ::bar!!
val inv = ::bar<!NOT_NULL_ASSERTION_ON_CALLABLE_REFERENCE!>!!<!>
inv(<!NO_VALUE_FOR_PARAMETER!>)<!>
}
}
fun poll71(): Flow<String> {
return flow {
val inv = ::bar2!!
val inv = ::bar2<!NOT_NULL_ASSERTION_ON_CALLABLE_REFERENCE!>!!<!>
inv()
}
}
fun poll72(): Flow<String> {
return flow {
val inv = ::bar3!!
val inv = ::bar3<!NOT_NULL_ASSERTION_ON_CALLABLE_REFERENCE!>!!<!>
inv()
}
}
fun poll73(): Flow<String> {
return flow {
val inv = ::bar4!!
val inv = ::bar4<!NOT_NULL_ASSERTION_ON_CALLABLE_REFERENCE!>!!<!>
inv
}
}
fun poll74(): Flow<String> {
return flow {
val inv = ::bar5!!
val inv = ::bar5<!NOT_NULL_ASSERTION_ON_CALLABLE_REFERENCE!>!!<!>
inv
}
}
fun poll75(): Flow<String> {
return flow {
val inv = ::Foo6!!
val inv = ::Foo6<!NOT_NULL_ASSERTION_ON_CALLABLE_REFERENCE!>!!<!>
inv
}
}
fun poll76(): Flow<String> {
return flow {
val inv = ::Foo7!!
val inv = ::Foo7<!NOT_NULL_ASSERTION_ON_CALLABLE_REFERENCE!>!!<!>
inv
}
}
@@ -119,28 +119,28 @@ fun poll5(): Flow<String> {
fun poll7(): Flow<String> {
return flow {
val inv = {}!!
val inv = {}<!NOT_NULL_ASSERTION_ON_LAMBDA_EXPRESSION!>!!<!>
inv()
}
}
fun poll71(): Flow<String> {
return flow {
val inv = {1f}!!
val inv = {1f}<!NOT_NULL_ASSERTION_ON_LAMBDA_EXPRESSION!>!!<!>
inv()
}
}
fun poll72(): Flow<String> {
return flow {
val inv = {{}}!!
val inv = {{}}<!NOT_NULL_ASSERTION_ON_LAMBDA_EXPRESSION!>!!<!>
inv()
}
}
fun poll73(): Flow<String> {
return flow {
val inv = ({})!!
val inv = ({})<!NOT_NULL_ASSERTION_ON_LAMBDA_EXPRESSION!>!!<!>
inv
}
}
@@ -189,7 +189,7 @@ fun poll85(): Flow<String> {
fun poll86(): Flow<String> {
return flow {
val inv = {({"1"})}!! in setOf({({"1f"})}!!)
val inv = {({"1"})}<!NOT_NULL_ASSERTION_ON_LAMBDA_EXPRESSION!>!!<!> in setOf({({"1f"})}<!NOT_NULL_ASSERTION_ON_LAMBDA_EXPRESSION!>!!<!>)
<!UNRESOLVED_REFERENCE!>inv<!>()
}
}
@@ -11,23 +11,23 @@ interface B {
fun test(u: A?, x: A?, y: A?, z: A?, w: A, v: A?) {
u?.b?.foo()!! // was UNNECESSARY_SAFE_CALL everywhere, because result type (of 'foo()') wasn't made nullable
u!!.b?.foo()!!
x?.b!!.foo()!!
u!!.b?.foo()<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>
x?.b!!.foo()<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>
// x?.b is not null
x!!.b!!.foo()!!
x!!.b<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>.foo()<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>
y?.nb?.foo()!!
y!!.nb?.foo()!!
z?.nb!!.foo()!!
z?.nb!!.foo()<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>
// z?.nb is not null
z!!.nb!!.foo()!!
z!!.nb!!.foo()<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>
w.b?.foo()!!
w.b!!.foo()!!
w.b?.foo()<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>
w.b<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>.foo()<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>
w.nb?.foo()!!
w.nb!!.foo()!!
w.nb!!.foo()<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>
v!!.b.foo()!!
v!!.b.foo()<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>
}
fun B?.bar(): Int = 1
@@ -36,6 +36,6 @@ fun B?.baz(): Int? = 1
fun doInt(i: Int) = i
fun test(a: A?) {
doInt(a?.b.bar()!!)
doInt(a?.b.bar()<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>)
doInt(a?.b.baz()!!)
}
}
@@ -5,7 +5,7 @@ import java.lang.Exception
fun <K> id(arg: K): K = arg
fun test() {
id(<!UNRESOLVED_REFERENCE!>unresolved<!>)!!
id(<!UNRESOLVED_REFERENCE!>unresolved<!>)<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>
<!UNRESOLVED_REFERENCE!>unresolved<!>!!!!
try {
id(<!UNRESOLVED_REFERENCE!>unresolved<!>)
@@ -234,37 +234,37 @@ fun poll66() {
}
fun poll7() {
val inv = ::bar!!
val inv = ::bar<!NOT_NULL_ASSERTION_ON_CALLABLE_REFERENCE!>!!<!>
inv(<!NO_VALUE_FOR_PARAMETER!>)<!>
}
fun poll71() {
val inv = ::bar2!!
val inv = ::bar2<!NOT_NULL_ASSERTION_ON_CALLABLE_REFERENCE!>!!<!>
inv()
}
fun poll72() {
val inv = ::bar3!!
val inv = ::bar3<!NOT_NULL_ASSERTION_ON_CALLABLE_REFERENCE!>!!<!>
inv(<!NO_VALUE_FOR_PARAMETER!>)<!>
}
fun poll73() {
val inv = ::bar4!!
val inv = ::bar4<!NOT_NULL_ASSERTION_ON_CALLABLE_REFERENCE!>!!<!>
inv
}
fun poll74() {
val inv = ::bar5!!
val inv = ::bar5<!NOT_NULL_ASSERTION_ON_CALLABLE_REFERENCE!>!!<!>
inv
}
fun poll75() {
val inv = ::Foo6!!
val inv = ::Foo6<!NOT_NULL_ASSERTION_ON_CALLABLE_REFERENCE!>!!<!>
inv
}
fun poll76() {
val inv = ::Foo7!!
val inv = ::Foo7<!NOT_NULL_ASSERTION_ON_CALLABLE_REFERENCE!>!!<!>
inv
}
@@ -5,35 +5,35 @@ fun main() {
val a : Int? = null
val b : Int? = null
checkSubtype<Int>(a!!)
a!! + 2
a!!.plus(2)
a!!.plus(b!!)
2.plus(b!!)
2 + b!!
a<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!> + 2
a<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>.plus(2)
a<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>.plus(b!!)
2.plus(b<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>)
2 + b<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>
val c = 1
c!!
c<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>
val d : Any? = null
if (d != null) {
d!!
d<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>
}
// smart cast isn't needed, but is reported due to KT-4294
if (d is String) {
d!!
d<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>
}
if (d is String?) {
if (d != null) {
d!!
d<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>
}
if (d is String) {
d!!
d<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>
}
}
val f : String = a!!
<!INAPPLICABLE_CANDIDATE!>checkSubtype<!><String>(a!!)
val f : String = a<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>
<!INAPPLICABLE_CANDIDATE!>checkSubtype<!><String>(a<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>)
}
@@ -10,7 +10,7 @@ fun main() {
x<!UNSAFE_CALL!>.<!>foo(y)
x!!.<!INAPPLICABLE_CANDIDATE!>foo<!>(y)
x.foo(y!!)
x!!.foo(y!!)
x<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>.foo(y<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>)
val a: Foo? = null
val b: Foo? = null
@@ -19,12 +19,12 @@ fun main() {
a<!UNSAFE_CALL!>.<!>foo(b<!UNSAFE_CALL!>.<!>foo(c))
a!!.foo(b<!UNSAFE_CALL!>.<!>foo(c))
a.foo(b!!.<!INAPPLICABLE_CANDIDATE!>foo<!>(c))
a!!.foo(b!!.<!INAPPLICABLE_CANDIDATE!>foo<!>(c))
a<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>.foo(b<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>.<!INAPPLICABLE_CANDIDATE!>foo<!>(c))
a.foo(b.foo(c!!))
a!!.foo(b.foo(c!!))
a.foo(b!!.foo(c!!))
a!!.foo(b!!.foo(c!!))
a<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>.foo(b.foo(c<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>))
a.foo(b<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>.foo(c<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>))
a<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>.foo(b<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>.foo(c<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>))
val z: Foo? = null
z!!.foo(z!!)
z!!.foo(z<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>)
}
@@ -11,7 +11,7 @@ fun main() {
if (x != null) {
foo(x)
foo(x!!)
foo(x<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>)
foo(x)
}
@@ -19,7 +19,7 @@ fun main() {
if (x != null) {
foo(x)
foo(x!!)
foo(x<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>)
foo(x)
} else {
<!INAPPLICABLE_CANDIDATE!>foo<!>(x)
@@ -28,12 +28,12 @@ fun main() {
}
foo(x)
foo(x!!)
foo(x<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>)
foo(x)
val y: Int? = null
y!!
y!!
y<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>
foo(y)
foo(y!!)
foo(y<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>)
}
@@ -11,7 +11,7 @@ fun f1(a: String?) {
}
fun f2(a: String) {
a!!
a<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>
checkSubtype<String>(a)
}
@@ -4,5 +4,5 @@ package kt2212
fun main() {
val x: Int? = 1
if (x == null) return
System.out.println(x.plus(x!!))
System.out.println(x.plus(x<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>))
}
@@ -11,7 +11,7 @@ fun foo() {
bar(if (x != null) x else return, x)
x + 2
bar(x, x!!)
bar(x, x<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>)
val y: Int? = 0
val z: Int? = 0
@@ -11,14 +11,14 @@ class Pair<A, B>(val a: A, val b: B)
fun main() {
val d : Long = 1
val period : Int? = null
if (period != null) Pair(d, checkSubtype<Int>(period!!)) else Pair(d, 1)
if (period != null) Pair(d, checkSubtype<Int>(period<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>)) else Pair(d, 1)
if (period != null) Pair(d, checkSubtype<Int>(period)) else Pair(d, 1)
}
fun foo() {
val x : Int? = 3
if (x != null) {
val u = checkSubtype<Int>(x!!)
val u = checkSubtype<Int>(x<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>)
val y = checkSubtype<Int>(x)
val z : Int = y
}
@@ -3,7 +3,7 @@ fun main() {
if (b != null) {
if (!b) {} // OK
if (b) {} // Error: Condition must be of type kotlin.Boolean, but is of type kotlin.Boolean?
if (b!!) {} // WARN: Unnecessary non-null assertion (!!) on a non-null receiver of type kotlin.Boolean?
if (b<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>) {} // WARN: Unnecessary non-null assertion (!!) on a non-null receiver of type kotlin.Boolean?
foo(b) // OK
}
}
@@ -17,8 +17,8 @@ fun test() {
takeNotNull(dependOn(dependOn(x!!)))
if (x != null) {
takeNotNull(dependOn(x)!!)
takeNotNull(dependOn(dependOn(x))!!)
takeNotNull(dependOn(dependOn(x)!!))
takeNotNull(dependOn(x)<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>)
takeNotNull(dependOn(dependOn(x))<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>)
takeNotNull(dependOn(dependOn(x)<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>))
}
}
}
@@ -6,7 +6,7 @@ fun <D> makeDefinitelyNotNull(arg: D?): D = TODO()
fun <N : Number?> test(arg: N) {
makeDefinitelyNotNull(arg) ?: 1
makeDefinitelyNotNull(arg)!!
makeDefinitelyNotNull(arg)<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>
makeDefinitelyNotNull(arg)?.toInt()
@@ -14,4 +14,4 @@ fun <N : Number?> test(arg: N) {
null -> false
else -> true
}
}
}
@@ -1,14 +1,14 @@
// !WITH_NEW_INFERENCE
fun <T> test(t: T): T {
if (t != null) {
return t!!
return t<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>
}
return t!!
}
fun <T> T.testThis(): String {
if (this != null) {
return this!!.toString()
return this<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>.toString()
}
return this!!.toString()
}
@@ -1,40 +0,0 @@
// !DIAGNOSTICS: -UNUSED_EXPRESSION -SENSELESS_COMPARISON -UNUSED_PARAMETER
// FILE: J.java
import org.jetbrains.annotations.*;
public class J {
@NotNull
public static J staticNN;
@Nullable
public static J staticN;
public static J staticJ;
}
// FILE: k.kt
fun test() {
// @NotNull platform type
val platformNN = J.staticNN
// @Nullable platform type
val platformN = J.staticN
// platform type with no annotation
val platformJ = J.staticJ
if (platformNN != null) {
platformNN!!
}
if (platformN != null) {
platformN!!
}
if (platformJ != null) {
platformJ!!
}
platformNN!!
platformN!!
platformJ!!
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// !DIAGNOSTICS: -UNUSED_EXPRESSION -SENSELESS_COMPARISON -UNUSED_PARAMETER
// FILE: J.java
@@ -1,27 +0,0 @@
// !DIAGNOSTICS: -UNUSED_PARAMETER
// FILE: J.java
import org.jetbrains.annotations.*;
public class J {
@NotNull
public static J staticNN;
}
// FILE: k.kt
fun test() {
// @NotNull platform type
val platformNN = J.staticNN
foo(platformNN!!)
val bar = Bar()
bar(platformNN!!)
}
fun foo(a: Any) {}
class Bar {
operator fun invoke(a: Any) {}
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// !DIAGNOSTICS: -UNUSED_PARAMETER
// FILE: J.java
@@ -15,7 +15,7 @@ fun list(j: J): Any {
a?.get(0)
if (a == null) {}
a!!
a<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>
a.get(0)
return a
@@ -5,4 +5,4 @@ fun lambda(x : Int?) = x?.<!UNRESOLVED_REFERENCE!>let<!> <!UNRESOLVED_REFERENCE!
y ->
if (y <!UNRESOLVED_REFERENCE!>><!> 0) return@l x
y
}!!
}<!NOT_NULL_ASSERTION_ON_LAMBDA_EXPRESSION!>!!<!>
@@ -28,7 +28,7 @@ fun testElvis(x: Any?) {
}
fun testExclExcl() {
val y = :: unresolved!!
val y = :: unresolved<!NOT_NULL_ASSERTION_ON_CALLABLE_REFERENCE!>!!<!>
}
fun testTry() {
@@ -1,24 +0,0 @@
//KT-4204 ConstraintSystem erased after resolution completion
package c
public abstract class TestBug1() {
public fun m3(position: Int) {
position(m1().second!!)
}
public fun m4(position: (Int)->Int) {
position(m1().second)
}
<!INCOMPATIBLE_MODIFIERS!>private<!> <!INCOMPATIBLE_MODIFIERS!>abstract<!> fun m1(): Pair<Int, Int>
private fun position(p: Int) {}
}
//from library
public class Pair<out A, out B> (
public val first: A,
public val second: B
)
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
//KT-4204 ConstraintSystem erased after resolution completion
package c
@@ -25,5 +25,5 @@ fun testDataFlowInfoAfterExclExcl(a: Int?) {
}
fun testUnnecessaryExclExcl(a: Int) {
doInt(a!!) //should be warning
doInt(a<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>) //should be warning
}
@@ -27,13 +27,13 @@ fun bar(o: Any) {
}
else {
order!!.doSomething()
order<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>.doSomething()
}
if (order?.notExpired() ?: true) {
}
else {
order!!.doSomething()
order<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>.doSomething()
}
}
@@ -25,7 +25,7 @@ public data class Tag(public var tagName: String) {
attributes.remove("id")
}
else {
attributes["id"] = value!!
attributes["id"] = value<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>
attributes["id"] = value
}
}
@@ -5,7 +5,7 @@ fun main() {
val value: String? = ""
if (value != null) {
foo(Pair("val", value))
foo(Pair("val", value!!))
foo(Pair("val", value<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>))
foo(Pair<String, String>("val", value))
}
}
@@ -3,10 +3,10 @@ operator fun <K, V> MutableMap<K, V>.set(k: K, v: V) {}
fun foo(a: MutableMap<String, String>, x: String?) {
a[x!!] = x
a[x] = x!!
a[x] = x<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>
}
fun foo1(a: MutableMap<String, String>, x: String?) {
<!INAPPLICABLE_CANDIDATE!>a[x]<!> = x!!
a[x!!] = x
a[x<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>] = x
}
@@ -1,6 +0,0 @@
fun calc(x: List<String>?): Int {
// After KT-5840 fix !! assertion should become unnecessary here
x?.get(x!!.size - 1)
// x?. or x!! above should not provide smart cast here
return x<!UNSAFE_CALL!>.<!>size
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
fun calc(x: List<String>?): Int {
// After KT-5840 fix !! assertion should become unnecessary here
x?.get(x<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>.size - 1)
@@ -10,5 +10,5 @@ fun foo(y: MyClass?): Int {
fun bar(y: MyClass?) {
y?.x!!.length
// !! is NOT necessary here, because y?.x != null
y!!.x
}
y<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>.x
}
@@ -10,7 +10,7 @@ fun test1(s: String?) {
fun test2(s: String?) {
assert(s!!.isEmpty())
s!!.length
s<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>.length
}
fun test3(s: String?) {
@@ -27,7 +27,7 @@ fun test4() {
fun test5() {
val s: String? = null;
assert(s!!.isEmpty())
s!!.length
s<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>.length
}
fun test6() {
@@ -1,5 +1,5 @@
fun foo1(p: Pair<Int?, Int>): Int {
if (p.first != null) return p.first!!
if (p.first != null) return p.first<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!>
return p.second
}