FIR checker: differentiate UNSAFE_CALL from INAPPLICABLE_CANDIDATE
To do so, inside the root cause of inapplicable candidate errors, we will record expected/actual type of receiver, if any. That will help identifying inapplicable calls on nullable receiver.
This commit is contained in:
committed by
Mikhail Glukhikh
parent
4b823eca21
commit
e72ddbcbfe
+2
-2
@@ -1,11 +1,11 @@
|
||||
// !WITH_NEW_INFERENCE
|
||||
fun foo() {
|
||||
var v: String? = null
|
||||
v.<!INAPPLICABLE_CANDIDATE!>length<!>
|
||||
v.<!UNSAFE_CALL!>length<!>
|
||||
v = "abc"
|
||||
v.length
|
||||
v = null
|
||||
v.<!INAPPLICABLE_CANDIDATE!>length<!>
|
||||
v.<!UNSAFE_CALL!>length<!>
|
||||
v = "abc"
|
||||
v.length
|
||||
}
|
||||
|
||||
+2
-2
@@ -23,7 +23,7 @@ fun bar(s: String?) {
|
||||
val hashCode = ss?.hashCode()
|
||||
ss = null
|
||||
if (hashCode != null) {
|
||||
ss.<!INAPPLICABLE_CANDIDATE!>hashCode<!>()
|
||||
ss.<!UNSAFE_CALL!>hashCode<!>()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,6 +41,6 @@ fun baz(arg: Some?) {
|
||||
val ss = arg?.s
|
||||
if (ss != null) {
|
||||
arg.hashCode()
|
||||
arg.s.<!INAPPLICABLE_CANDIDATE!>hashCode<!>()
|
||||
arg.s.<!UNSAFE_CALL!>hashCode<!>()
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -37,7 +37,7 @@ fun test3() {
|
||||
catch (e: B) {
|
||||
return
|
||||
}
|
||||
a.<!INAPPLICABLE_CANDIDATE!>hashCode<!>() // a is nullable here
|
||||
a.<!UNSAFE_CALL!>hashCode<!>() // a is nullable here
|
||||
}
|
||||
fun test4() {
|
||||
var a: Int? = null
|
||||
@@ -50,7 +50,7 @@ fun test4() {
|
||||
catch (e: B) {
|
||||
return
|
||||
}
|
||||
a.<!INAPPLICABLE_CANDIDATE!>hashCode<!>() // a is nullable here
|
||||
a.<!UNSAFE_CALL!>hashCode<!>() // a is nullable here
|
||||
}
|
||||
fun test5() {
|
||||
var a: Int?// = null
|
||||
@@ -76,5 +76,5 @@ fun test6() {
|
||||
finally {
|
||||
a = null
|
||||
}
|
||||
a.<!INAPPLICABLE_CANDIDATE!>hashCode<!>() // a is null here
|
||||
a.<!UNSAFE_CALL!>hashCode<!>() // a is null here
|
||||
}
|
||||
|
||||
+2
-2
@@ -2,7 +2,7 @@
|
||||
fun foo() {
|
||||
var v: String? = "xyz"
|
||||
// It is possible in principle to provide smart cast here
|
||||
v.<!INAPPLICABLE_CANDIDATE!>length<!>
|
||||
v.<!UNSAFE_CALL!>length<!>
|
||||
v = null
|
||||
v.<!INAPPLICABLE_CANDIDATE!>length<!>
|
||||
v.<!UNSAFE_CALL!>length<!>
|
||||
}
|
||||
|
||||
+1
-1
@@ -12,7 +12,7 @@ fun foo(): Bar {
|
||||
var y: Bar? = Bar()
|
||||
while (x != null) {
|
||||
// Here call is unsafe because of initialization and also inner loop
|
||||
y.<!INAPPLICABLE_CANDIDATE!>next<!>()
|
||||
y.<!UNSAFE_CALL!>next<!>()
|
||||
while (y != null) {
|
||||
if (x == y)
|
||||
// x is not null because of outer while
|
||||
|
||||
+1
-1
@@ -12,7 +12,7 @@ operator fun Long?.inc() = this?.let { it + 1 }
|
||||
fun bar(arg: Long?): Long {
|
||||
var i = arg
|
||||
if (i++ == 5L) {
|
||||
return i<!INAPPLICABLE_CANDIDATE!>--<!> + i
|
||||
return i<!UNSAFE_CALL!>--<!> + i
|
||||
}
|
||||
if (i++ == 7L) {
|
||||
return i++ <!NONE_APPLICABLE!>+<!> i
|
||||
|
||||
+1
-1
@@ -3,6 +3,6 @@ operator fun Int?.inc(): Int? { return this }
|
||||
public fun box(arg: Int?) : Int? {
|
||||
var i : Int? = arg
|
||||
var j = i++
|
||||
j.<!INAPPLICABLE_CANDIDATE!>toInt<!>()
|
||||
j.<!UNSAFE_CALL!>toInt<!>()
|
||||
return i
|
||||
}
|
||||
|
||||
Vendored
+1
-1
@@ -9,5 +9,5 @@ public fun box() {
|
||||
// type of j should be MyClass?
|
||||
var j = ++i
|
||||
// j is null so call should be unsafe
|
||||
j.<!INAPPLICABLE_CANDIDATE!>hashCode<!>()
|
||||
j.<!UNSAFE_CALL!>hashCode<!>()
|
||||
}
|
||||
|
||||
+1
-1
@@ -3,6 +3,6 @@ operator fun Int?.inc(): Int? { return this }
|
||||
public fun box(arg: Int?) : Int? {
|
||||
var i = arg
|
||||
var j = ++i
|
||||
j.<!INAPPLICABLE_CANDIDATE!>toInt<!>()
|
||||
j.<!UNSAFE_CALL!>toInt<!>()
|
||||
return ++j
|
||||
}
|
||||
|
||||
+1
-1
@@ -10,5 +10,5 @@ fun foo() {
|
||||
} catch (ex: Exception) {}
|
||||
bar(s)
|
||||
if (s != null) { }
|
||||
s.<!INAPPLICABLE_CANDIDATE!>hashCode<!>()
|
||||
s.<!UNSAFE_CALL!>hashCode<!>()
|
||||
}
|
||||
+1
-1
@@ -6,5 +6,5 @@ fun foo() {
|
||||
try {
|
||||
s = null
|
||||
} catch (ex: Exception) {}
|
||||
s.<!INAPPLICABLE_CANDIDATE!>hashCode<!>()
|
||||
s.<!UNSAFE_CALL!>hashCode<!>()
|
||||
}
|
||||
+1
-1
@@ -12,5 +12,5 @@ fun foo() {
|
||||
finally {
|
||||
bar()
|
||||
}
|
||||
s.<!INAPPLICABLE_CANDIDATE!>hashCode<!>()
|
||||
s.<!UNSAFE_CALL!>hashCode<!>()
|
||||
}
|
||||
+1
-1
@@ -6,5 +6,5 @@ fun foo() {
|
||||
try {
|
||||
s = null
|
||||
} catch (ex: Exception) {}
|
||||
s.<!INAPPLICABLE_CANDIDATE!>hashCode<!>()
|
||||
s.<!UNSAFE_CALL!>hashCode<!>()
|
||||
}
|
||||
+1
-1
@@ -14,7 +14,7 @@ class MyClass {
|
||||
var res = 0
|
||||
m = create()
|
||||
// See KT-7428
|
||||
<!INAPPLICABLE_CANDIDATE!>for ((k, v) in m)
|
||||
<!UNSAFE_CALL!>for ((k, v) in m)
|
||||
res += (k.length + v.length)<!>
|
||||
return res
|
||||
}
|
||||
|
||||
@@ -2,5 +2,5 @@
|
||||
fun foo(): Int {
|
||||
var s: String? = "abc"
|
||||
s = null
|
||||
return s.<!INAPPLICABLE_CANDIDATE!>length<!>
|
||||
return s.<!UNSAFE_CALL!>length<!>
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user