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,7 +13,7 @@ fun g(a: SomeClass?) {
// 'a' can be cast to SomeSubClass
a.hashCode()
a.foo
(a as? SomeSubClass).<!INAPPLICABLE_CANDIDATE!>foo<!>
(a as? SomeSubClass).<!UNSAFE_CALL!>foo<!>
(a as SomeSubClass).foo
}
val b = (a as? SomeSubClass)?.foo
@@ -21,7 +21,7 @@ fun g(a: SomeClass?) {
// 'a' can be cast to SomeSubClass
a.hashCode()
a.foo
(a as? SomeSubClass).<!INAPPLICABLE_CANDIDATE!>foo<!>
(a as? SomeSubClass).<!UNSAFE_CALL!>foo<!>
(a as SomeSubClass).foo
}
val c = a as? SomeSubClass
@@ -29,7 +29,7 @@ fun g(a: SomeClass?) {
// 'a' and 'c' can be cast to SomeSubClass
a.hashCode()
a.foo
(a as? SomeSubClass).<!INAPPLICABLE_CANDIDATE!>foo<!>
(a as? SomeSubClass).<!UNSAFE_CALL!>foo<!>
c.hashCode()
c.foo
}
@@ -13,7 +13,7 @@ fun g(a: SomeClass?) {
// 'a' can be cast to SomeSubClass
a.hashCode()
a.foo
(a as? SomeSubClass).<!INAPPLICABLE_CANDIDATE!>foo<!>
(a as? SomeSubClass).<!UNSAFE_CALL!>foo<!>
(a as SomeSubClass).foo
}
val b = (a as? SomeSubClass)?.foo
@@ -21,7 +21,7 @@ fun g(a: SomeClass?) {
// 'a' can be cast to SomeSubClass
a.hashCode()
a.foo
(a as? SomeSubClass).<!INAPPLICABLE_CANDIDATE!>foo<!>
(a as? SomeSubClass).<!UNSAFE_CALL!>foo<!>
(a as SomeSubClass).foo
}
val c = a as? SomeSubClass
@@ -29,7 +29,7 @@ fun g(a: SomeClass?) {
// 'a' and 'c' can be cast to SomeSubClass
a.hashCode()
a.foo
(a as? SomeSubClass).<!INAPPLICABLE_CANDIDATE!>foo<!>
(a as? SomeSubClass).<!UNSAFE_CALL!>foo<!>
c.hashCode()
c.foo
}
@@ -18,18 +18,18 @@ fun g(a: SomeClass?) {
b = "Hello"
if (b != null) {
// 'a' cannot be cast to SomeSubClass!
a.<!INAPPLICABLE_CANDIDATE!>hashCode<!>()
a.<!UNSAFE_CALL!>hashCode<!>()
a.<!UNRESOLVED_REFERENCE!>foo<!>
(a as? SomeSubClass).<!INAPPLICABLE_CANDIDATE!>foo<!>
(a as? SomeSubClass).<!UNSAFE_CALL!>foo<!>
(a as SomeSubClass).foo
}
var c = a as? SomeSubClass
c = Impl
if (c != null) {
// 'a' cannot be cast to SomeSubClass
a.<!INAPPLICABLE_CANDIDATE!>hashCode<!>()
a.<!UNSAFE_CALL!>hashCode<!>()
a.<!UNRESOLVED_REFERENCE!>foo<!>
(a as? SomeSubClass).<!INAPPLICABLE_CANDIDATE!>foo<!>
(a as? SomeSubClass).<!UNSAFE_CALL!>foo<!>
c.hashCode()
c.foo
}
@@ -41,18 +41,18 @@ fun f(a: SomeClass?) {
if (aa as? SomeSubClass != null) {
aa = null
// 'aa' cannot be cast to SomeSubClass
aa.<!INAPPLICABLE_CANDIDATE!>hashCode<!>()
aa.<!UNSAFE_CALL!>hashCode<!>()
aa.<!UNRESOLVED_REFERENCE!>foo<!>
(aa as? SomeSubClass).<!INAPPLICABLE_CANDIDATE!>foo<!>
(aa as? SomeSubClass).<!UNSAFE_CALL!>foo<!>
(aa as SomeSubClass).foo
}
val b = (aa as? SomeSubClass)?.foo
aa = null
if (b != null) {
// 'aa' cannot be cast to SomeSubClass
aa.<!INAPPLICABLE_CANDIDATE!>hashCode<!>()
aa.<!UNSAFE_CALL!>hashCode<!>()
aa.<!UNRESOLVED_REFERENCE!>foo<!>
(aa as? SomeSubClass).<!INAPPLICABLE_CANDIDATE!>foo<!>
(aa as? SomeSubClass).<!UNSAFE_CALL!>foo<!>
(aa as SomeSubClass).foo
}
aa = a
@@ -61,7 +61,7 @@ fun f(a: SomeClass?) {
// 'c' can be cast to SomeSubClass
aa.hashCode()
aa.foo
(aa as? SomeSubClass).<!INAPPLICABLE_CANDIDATE!>foo<!>
(aa as? SomeSubClass).<!UNSAFE_CALL!>foo<!>
c.hashCode()
c.foo
}