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:
Jinseong Jeon
2021-01-26 16:03:27 -08:00
committed by Mikhail Glukhikh
parent 4b823eca21
commit e72ddbcbfe
275 changed files with 1426 additions and 1388 deletions
@@ -13,15 +13,15 @@ fun test1() {
try {
x = null
} catch (e: Exception) {
x.<!INAPPLICABLE_CANDIDATE!>length<!> // smartcast shouldn't be allowed (OOME could happen after `x = null`)
x.<!UNSAFE_CALL!>length<!> // smartcast shouldn't be allowed (OOME could happen after `x = null`)
throw e
}
finally {
// smartcast shouldn't be allowed, `x = null` could've happened
x.<!INAPPLICABLE_CANDIDATE!>length<!>
x.<!UNSAFE_CALL!>length<!>
}
// smartcast shouldn't be allowed, `x = null` could've happened
x.<!INAPPLICABLE_CANDIDATE!>length<!>
x.<!UNSAFE_CALL!>length<!>
}
// With old DFA of try/catch info about unsound smartcasts after try
@@ -33,12 +33,12 @@ fun test2() {
try {
x = null
} catch (e: Exception) {
x.<!INAPPLICABLE_CANDIDATE!>length<!>
x.<!UNSAFE_CALL!>length<!>
}
finally {
x.<!INAPPLICABLE_CANDIDATE!>length<!>
x.<!UNSAFE_CALL!>length<!>
}
x.<!INAPPLICABLE_CANDIDATE!>length<!>
x.<!UNSAFE_CALL!>length<!>
}
fun test3() {
@@ -49,7 +49,7 @@ fun test3() {
} catch (e: Exception) {
t2 = null
}
t2.<!INAPPLICABLE_CANDIDATE!>not<!>() // wrong smartcast, NPE
t2.<!UNSAFE_CALL!>not<!>() // wrong smartcast, NPE
}
}
@@ -59,7 +59,7 @@ fun test4() {
try {
t2 = null
} finally { }
t2.<!INAPPLICABLE_CANDIDATE!>not<!>() // wrong smartcast, NPE
t2.<!UNSAFE_CALL!>not<!>() // wrong smartcast, NPE
}
}
@@ -80,10 +80,10 @@ fun test5() {
}
finally {
s1.length
s2.<!INAPPLICABLE_CANDIDATE!>length<!>
s2.<!UNSAFE_CALL!>length<!>
}
s1.length
s2.<!INAPPLICABLE_CANDIDATE!>length<!>
s2.<!UNSAFE_CALL!>length<!>
}
fun test6(s1: String?, s2: String?) {
@@ -97,10 +97,10 @@ fun test6(s1: String?, s2: String?) {
return
}
finally {
s.<!INAPPLICABLE_CANDIDATE!>length<!>
s.<!UNSAFE_CALL!>length<!>
requireNotNull(s2)
}
s.<!INAPPLICABLE_CANDIDATE!>length<!>
s1.<!INAPPLICABLE_CANDIDATE!>length<!>
s.<!UNSAFE_CALL!>length<!>
s1.<!UNSAFE_CALL!>length<!>
s2.length
}