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
@@ -15,7 +15,7 @@ fun test_2(x: Int?) {
|
|||||||
} else {
|
} else {
|
||||||
x
|
x
|
||||||
}
|
}
|
||||||
y.<!INAPPLICABLE_CANDIDATE{LT}!><!INAPPLICABLE_CANDIDATE{PSI}!>inc<!>()<!>
|
y.<!UNSAFE_CALL{LT}!><!UNSAFE_CALL{PSI}!>inc<!>()<!>
|
||||||
}
|
}
|
||||||
|
|
||||||
fun test_3(x: Int?) {
|
fun test_3(x: Int?) {
|
||||||
|
|||||||
+1
-1
@@ -34,7 +34,7 @@ fun test3(x: AnotherClass?) {
|
|||||||
fun test4(x: SomeClass?) {
|
fun test4(x: SomeClass?) {
|
||||||
val bar = x?.bar
|
val bar = x?.bar
|
||||||
if (bar != null) {
|
if (bar != null) {
|
||||||
x.bar.<!INAPPLICABLE_CANDIDATE!>length<!>
|
x.bar.<!UNSAFE_CALL!>length<!>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ fun test_3(a: A?, b: Boolean) {
|
|||||||
if (b && a!!.foo()) {
|
if (b && a!!.foo()) {
|
||||||
a.foo() // OK
|
a.foo() // OK
|
||||||
}
|
}
|
||||||
a.<!INAPPLICABLE_CANDIDATE{LT}!><!INAPPLICABLE_CANDIDATE{PSI}!>foo<!>()<!> // Bad
|
a.<!UNSAFE_CALL{LT}!><!UNSAFE_CALL{PSI}!>foo<!>()<!> // Bad
|
||||||
}
|
}
|
||||||
|
|
||||||
fun test_4(a: A?, b: Boolean) {
|
fun test_4(a: A?, b: Boolean) {
|
||||||
@@ -38,9 +38,9 @@ fun test_4(a: A?, b: Boolean) {
|
|||||||
|
|
||||||
fun test_5(a: A?, b: Boolean) {
|
fun test_5(a: A?, b: Boolean) {
|
||||||
if (b || a!!.foo()) {
|
if (b || a!!.foo()) {
|
||||||
a.<!INAPPLICABLE_CANDIDATE{LT}!><!INAPPLICABLE_CANDIDATE{PSI}!>foo<!>()<!>
|
a.<!UNSAFE_CALL{LT}!><!UNSAFE_CALL{PSI}!>foo<!>()<!>
|
||||||
}
|
}
|
||||||
a.<!INAPPLICABLE_CANDIDATE{LT}!><!INAPPLICABLE_CANDIDATE{PSI}!>foo<!>()<!>
|
a.<!UNSAFE_CALL{LT}!><!UNSAFE_CALL{PSI}!>foo<!>()<!>
|
||||||
}
|
}
|
||||||
|
|
||||||
fun <X : A?> test_6(x: X) {
|
fun <X : A?> test_6(x: X) {
|
||||||
|
|||||||
+8
-8
@@ -8,13 +8,13 @@ fun test_1(b: Boolean?) {
|
|||||||
if ((b == true) == true) {
|
if ((b == true) == true) {
|
||||||
b.not() // OK
|
b.not() // OK
|
||||||
} else {
|
} else {
|
||||||
b.<!INAPPLICABLE_CANDIDATE{LT}!><!INAPPLICABLE_CANDIDATE{PSI}!>not<!>()<!> // Bad
|
b.<!UNSAFE_CALL{LT}!><!UNSAFE_CALL{PSI}!>not<!>()<!> // Bad
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun test_2(b: Boolean?) {
|
fun test_2(b: Boolean?) {
|
||||||
if ((b == true) != true) {
|
if ((b == true) != true) {
|
||||||
b.<!INAPPLICABLE_CANDIDATE{LT}!><!INAPPLICABLE_CANDIDATE{PSI}!>not<!>()<!> // Bad
|
b.<!UNSAFE_CALL{LT}!><!UNSAFE_CALL{PSI}!>not<!>()<!> // Bad
|
||||||
} else {
|
} else {
|
||||||
b.not() // OK
|
b.not() // OK
|
||||||
}
|
}
|
||||||
@@ -22,7 +22,7 @@ fun test_2(b: Boolean?) {
|
|||||||
|
|
||||||
fun test_3(b: Boolean?) {
|
fun test_3(b: Boolean?) {
|
||||||
if ((b == true) == false) {
|
if ((b == true) == false) {
|
||||||
b.<!INAPPLICABLE_CANDIDATE{LT}!><!INAPPLICABLE_CANDIDATE{PSI}!>not<!>()<!> // Bad
|
b.<!UNSAFE_CALL{LT}!><!UNSAFE_CALL{PSI}!>not<!>()<!> // Bad
|
||||||
} else {
|
} else {
|
||||||
b.not() // OK
|
b.not() // OK
|
||||||
}
|
}
|
||||||
@@ -32,13 +32,13 @@ fun test_4(b: Boolean?) {
|
|||||||
if ((b == true) != false) {
|
if ((b == true) != false) {
|
||||||
b.not() // OK
|
b.not() // OK
|
||||||
} else {
|
} else {
|
||||||
b.<!INAPPLICABLE_CANDIDATE{LT}!><!INAPPLICABLE_CANDIDATE{PSI}!>not<!>()<!> // Bad
|
b.<!UNSAFE_CALL{LT}!><!UNSAFE_CALL{PSI}!>not<!>()<!> // Bad
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun test_5(b: Boolean?) {
|
fun test_5(b: Boolean?) {
|
||||||
if ((b != true) == true) {
|
if ((b != true) == true) {
|
||||||
b.<!INAPPLICABLE_CANDIDATE{LT}!><!INAPPLICABLE_CANDIDATE{PSI}!>not<!>()<!> // Bad
|
b.<!UNSAFE_CALL{LT}!><!UNSAFE_CALL{PSI}!>not<!>()<!> // Bad
|
||||||
} else {
|
} else {
|
||||||
b.not() // OK
|
b.not() // OK
|
||||||
}
|
}
|
||||||
@@ -48,7 +48,7 @@ fun test_6(b: Boolean?) {
|
|||||||
if ((b != true) != true) {
|
if ((b != true) != true) {
|
||||||
b.not() // OK
|
b.not() // OK
|
||||||
} else {
|
} else {
|
||||||
b.<!INAPPLICABLE_CANDIDATE{LT}!><!INAPPLICABLE_CANDIDATE{PSI}!>not<!>()<!> // Bad
|
b.<!UNSAFE_CALL{LT}!><!UNSAFE_CALL{PSI}!>not<!>()<!> // Bad
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -56,13 +56,13 @@ fun test_7(b: Boolean?) {
|
|||||||
if ((b != true) == false) {
|
if ((b != true) == false) {
|
||||||
b.not() // OK
|
b.not() // OK
|
||||||
} else {
|
} else {
|
||||||
b.<!INAPPLICABLE_CANDIDATE{LT}!><!INAPPLICABLE_CANDIDATE{PSI}!>not<!>()<!> // Bad
|
b.<!UNSAFE_CALL{LT}!><!UNSAFE_CALL{PSI}!>not<!>()<!> // Bad
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun test_8(b: Boolean?) {
|
fun test_8(b: Boolean?) {
|
||||||
if ((b != true) != false) {
|
if ((b != true) != false) {
|
||||||
b.<!INAPPLICABLE_CANDIDATE{LT}!><!INAPPLICABLE_CANDIDATE{PSI}!>not<!>()<!> // Bad
|
b.<!UNSAFE_CALL{LT}!><!UNSAFE_CALL{PSI}!>not<!>()<!> // Bad
|
||||||
} else {
|
} else {
|
||||||
b.not() // OK
|
b.not() // OK
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-6
@@ -34,24 +34,24 @@ fun test_4(a: A?) {
|
|||||||
|
|
||||||
fun test_5(a: A?) {
|
fun test_5(a: A?) {
|
||||||
a == null || throw Exception()
|
a == null || throw Exception()
|
||||||
a.<!INAPPLICABLE_CANDIDATE{LT}!><!INAPPLICABLE_CANDIDATE{PSI}!>foo<!>()<!>
|
a.<!UNSAFE_CALL{LT}!><!UNSAFE_CALL{PSI}!>foo<!>()<!>
|
||||||
}
|
}
|
||||||
|
|
||||||
fun teat_6(a: A?) {
|
fun teat_6(a: A?) {
|
||||||
a != null && throw Exception()
|
a != null && throw Exception()
|
||||||
a.<!INAPPLICABLE_CANDIDATE{LT}!><!INAPPLICABLE_CANDIDATE{PSI}!>foo<!>()<!>
|
a.<!UNSAFE_CALL{LT}!><!UNSAFE_CALL{PSI}!>foo<!>()<!>
|
||||||
}
|
}
|
||||||
|
|
||||||
fun test_7(a: A?) {
|
fun test_7(a: A?) {
|
||||||
if (a == null || throw Exception()) {
|
if (a == null || throw Exception()) {
|
||||||
a.<!INAPPLICABLE_CANDIDATE{LT}!><!INAPPLICABLE_CANDIDATE{PSI}!>foo<!>()<!>
|
a.<!UNSAFE_CALL{LT}!><!UNSAFE_CALL{PSI}!>foo<!>()<!>
|
||||||
}
|
}
|
||||||
a.<!INAPPLICABLE_CANDIDATE{LT}!><!INAPPLICABLE_CANDIDATE{PSI}!>foo<!>()<!>
|
a.<!UNSAFE_CALL{LT}!><!UNSAFE_CALL{PSI}!>foo<!>()<!>
|
||||||
}
|
}
|
||||||
|
|
||||||
fun test_8(a: A?) {
|
fun test_8(a: A?) {
|
||||||
if (a != null && throw Exception()) {
|
if (a != null && throw Exception()) {
|
||||||
a.<!INAPPLICABLE_CANDIDATE{LT}!><!INAPPLICABLE_CANDIDATE{PSI}!>foo<!>()<!>
|
a.<!UNSAFE_CALL{LT}!><!UNSAFE_CALL{PSI}!>foo<!>()<!>
|
||||||
}
|
}
|
||||||
a.<!INAPPLICABLE_CANDIDATE{LT}!><!INAPPLICABLE_CANDIDATE{PSI}!>foo<!>()<!>
|
a.<!UNSAFE_CALL{LT}!><!UNSAFE_CALL{PSI}!>foo<!>()<!>
|
||||||
}
|
}
|
||||||
|
|||||||
compiler/fir/analysis-tests/testData/resolve/smartcasts/boundSmartcasts/boundSmartcastsInBranches.kt
Vendored
+4
-4
@@ -104,18 +104,18 @@ fun test_7() {
|
|||||||
|
|
||||||
if (x != null) {
|
if (x != null) {
|
||||||
x.length // OK
|
x.length // OK
|
||||||
y.<!INAPPLICABLE_CANDIDATE!>length<!> // Bad
|
y.<!UNSAFE_CALL!>length<!> // Bad
|
||||||
z.length // OK
|
z.length // OK
|
||||||
}
|
}
|
||||||
if (y != null) {
|
if (y != null) {
|
||||||
x.<!INAPPLICABLE_CANDIDATE!>length<!> // Bad
|
x.<!UNSAFE_CALL!>length<!> // Bad
|
||||||
y.length // OK
|
y.length // OK
|
||||||
z.<!INAPPLICABLE_CANDIDATE!>length<!> // Bad
|
z.<!UNSAFE_CALL!>length<!> // Bad
|
||||||
}
|
}
|
||||||
|
|
||||||
if (z != null) {
|
if (z != null) {
|
||||||
x.length // OK
|
x.length // OK
|
||||||
y.<!INAPPLICABLE_CANDIDATE!>length<!> // Bad
|
y.<!UNSAFE_CALL!>length<!> // Bad
|
||||||
z.length // OK
|
z.length // OK
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-4
@@ -16,12 +16,12 @@ fun test_1(x: A, y: A?) {
|
|||||||
|
|
||||||
fun test_2(x: A?, y: A?) {
|
fun test_2(x: A?, y: A?) {
|
||||||
if (x == y) {
|
if (x == y) {
|
||||||
x.<!INAPPLICABLE_CANDIDATE{LT}!><!INAPPLICABLE_CANDIDATE{PSI}!>foo<!>()<!>
|
x.<!UNSAFE_CALL{LT}!><!UNSAFE_CALL{PSI}!>foo<!>()<!>
|
||||||
y.<!INAPPLICABLE_CANDIDATE{LT}!><!INAPPLICABLE_CANDIDATE{PSI}!>foo<!>()<!>
|
y.<!UNSAFE_CALL{LT}!><!UNSAFE_CALL{PSI}!>foo<!>()<!>
|
||||||
}
|
}
|
||||||
if (x === y) {
|
if (x === y) {
|
||||||
x.<!INAPPLICABLE_CANDIDATE{LT}!><!INAPPLICABLE_CANDIDATE{PSI}!>foo<!>()<!>
|
x.<!UNSAFE_CALL{LT}!><!UNSAFE_CALL{PSI}!>foo<!>()<!>
|
||||||
y.<!INAPPLICABLE_CANDIDATE{LT}!><!INAPPLICABLE_CANDIDATE{PSI}!>foo<!>()<!>
|
y.<!UNSAFE_CALL{LT}!><!UNSAFE_CALL{PSI}!>foo<!>()<!>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -39,18 +39,18 @@ fun test_1(x: A?) {
|
|||||||
if (x != null) {
|
if (x != null) {
|
||||||
x.foo()
|
x.foo()
|
||||||
} else {
|
} else {
|
||||||
x.<!INAPPLICABLE_CANDIDATE{LT}!><!INAPPLICABLE_CANDIDATE{PSI}!>foo<!>()<!>
|
x.<!UNSAFE_CALL{LT}!><!UNSAFE_CALL{PSI}!>foo<!>()<!>
|
||||||
}
|
}
|
||||||
x.<!INAPPLICABLE_CANDIDATE{LT}!><!INAPPLICABLE_CANDIDATE{PSI}!>foo<!>()<!>
|
x.<!UNSAFE_CALL{LT}!><!UNSAFE_CALL{PSI}!>foo<!>()<!>
|
||||||
}
|
}
|
||||||
|
|
||||||
fun test_2(x: A?) {
|
fun test_2(x: A?) {
|
||||||
if (x == null) {
|
if (x == null) {
|
||||||
x.<!INAPPLICABLE_CANDIDATE{LT}!><!INAPPLICABLE_CANDIDATE{PSI}!>foo<!>()<!>
|
x.<!UNSAFE_CALL{LT}!><!UNSAFE_CALL{PSI}!>foo<!>()<!>
|
||||||
} else {
|
} else {
|
||||||
x.foo()
|
x.foo()
|
||||||
}
|
}
|
||||||
x.<!INAPPLICABLE_CANDIDATE{LT}!><!INAPPLICABLE_CANDIDATE{PSI}!>foo<!>()<!>
|
x.<!UNSAFE_CALL{LT}!><!UNSAFE_CALL{PSI}!>foo<!>()<!>
|
||||||
}
|
}
|
||||||
|
|
||||||
fun test_3(x: A?) {
|
fun test_3(x: A?) {
|
||||||
@@ -67,8 +67,8 @@ fun test_5(q: Q?) {
|
|||||||
// `q.data` is a property that has an open getter, so we can NOT smartcast it to non-nullable MyData.
|
// `q.data` is a property that has an open getter, so we can NOT smartcast it to non-nullable MyData.
|
||||||
if (q?.data?.s?.inc() != null) {
|
if (q?.data?.s?.inc() != null) {
|
||||||
q.data // good
|
q.data // good
|
||||||
q.data.<!INAPPLICABLE_CANDIDATE!>s<!> // should be bad
|
q.data.<!UNSAFE_CALL!>s<!> // should be bad
|
||||||
q.data.<!INAPPLICABLE_CANDIDATE!>s<!>.inc() // should be bad
|
q.data.<!UNSAFE_CALL!>s<!>.inc() // should be bad
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,15 +76,15 @@ fun test_6(q: Q?) {
|
|||||||
// `q.data` is a property that has an open getter, so we can NOT smartcast it to non-nullable MyData.
|
// `q.data` is a property that has an open getter, so we can NOT smartcast it to non-nullable MyData.
|
||||||
q?.data?.s?.inc() ?: return
|
q?.data?.s?.inc() ?: return
|
||||||
q.data // good
|
q.data // good
|
||||||
q.data.<!INAPPLICABLE_CANDIDATE!>s<!> // should be bad
|
q.data.<!UNSAFE_CALL!>s<!> // should be bad
|
||||||
q.data.<!INAPPLICABLE_CANDIDATE!>s<!>.inc() // should be bad
|
q.data.<!UNSAFE_CALL!>s<!>.inc() // should be bad
|
||||||
}
|
}
|
||||||
|
|
||||||
fun test_7(q: Q?) {
|
fun test_7(q: Q?) {
|
||||||
if (q?.fdata()?.fs()?.inc() != null) {
|
if (q?.fdata()?.fs()?.inc() != null) {
|
||||||
q.fdata() // good
|
q.fdata() // good
|
||||||
q.fdata().<!INAPPLICABLE_CANDIDATE{LT}!><!INAPPLICABLE_CANDIDATE{PSI}!>fs<!>()<!> // bad
|
q.fdata().<!UNSAFE_CALL{LT}!><!UNSAFE_CALL{PSI}!>fs<!>()<!> // bad
|
||||||
q.fdata().<!INAPPLICABLE_CANDIDATE{LT}!><!INAPPLICABLE_CANDIDATE{PSI}!>fs<!>()<!>.inc() // bad
|
q.fdata().<!UNSAFE_CALL{LT}!><!UNSAFE_CALL{PSI}!>fs<!>()<!>.inc() // bad
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -98,44 +98,44 @@ fun test_9(a: Int, b: Int?) {
|
|||||||
if (a == b) {
|
if (a == b) {
|
||||||
b.inc()
|
b.inc()
|
||||||
}
|
}
|
||||||
b.<!INAPPLICABLE_CANDIDATE{LT}!><!INAPPLICABLE_CANDIDATE{PSI}!>inc<!>()<!>
|
b.<!UNSAFE_CALL{LT}!><!UNSAFE_CALL{PSI}!>inc<!>()<!>
|
||||||
|
|
||||||
if (a === b) {
|
if (a === b) {
|
||||||
b.inc()
|
b.inc()
|
||||||
}
|
}
|
||||||
b.<!INAPPLICABLE_CANDIDATE{LT}!><!INAPPLICABLE_CANDIDATE{PSI}!>inc<!>()<!>
|
b.<!UNSAFE_CALL{LT}!><!UNSAFE_CALL{PSI}!>inc<!>()<!>
|
||||||
|
|
||||||
if (b == a) {
|
if (b == a) {
|
||||||
b.inc()
|
b.inc()
|
||||||
}
|
}
|
||||||
b.<!INAPPLICABLE_CANDIDATE{LT}!><!INAPPLICABLE_CANDIDATE{PSI}!>inc<!>()<!>
|
b.<!UNSAFE_CALL{LT}!><!UNSAFE_CALL{PSI}!>inc<!>()<!>
|
||||||
|
|
||||||
if (b === a) {
|
if (b === a) {
|
||||||
b.inc()
|
b.inc()
|
||||||
}
|
}
|
||||||
b.<!INAPPLICABLE_CANDIDATE{LT}!><!INAPPLICABLE_CANDIDATE{PSI}!>inc<!>()<!>
|
b.<!UNSAFE_CALL{LT}!><!UNSAFE_CALL{PSI}!>inc<!>()<!>
|
||||||
}
|
}
|
||||||
|
|
||||||
fun test_10(a: Int?, b: Int?) {
|
fun test_10(a: Int?, b: Int?) {
|
||||||
if (a == b) {
|
if (a == b) {
|
||||||
b.<!INAPPLICABLE_CANDIDATE{LT}!><!INAPPLICABLE_CANDIDATE{PSI}!>inc<!>()<!>
|
b.<!UNSAFE_CALL{LT}!><!UNSAFE_CALL{PSI}!>inc<!>()<!>
|
||||||
}
|
}
|
||||||
b.<!INAPPLICABLE_CANDIDATE{LT}!><!INAPPLICABLE_CANDIDATE{PSI}!>inc<!>()<!>
|
b.<!UNSAFE_CALL{LT}!><!UNSAFE_CALL{PSI}!>inc<!>()<!>
|
||||||
|
|
||||||
if (a === b) {
|
if (a === b) {
|
||||||
b.<!INAPPLICABLE_CANDIDATE{LT}!><!INAPPLICABLE_CANDIDATE{PSI}!>inc<!>()<!>
|
b.<!UNSAFE_CALL{LT}!><!UNSAFE_CALL{PSI}!>inc<!>()<!>
|
||||||
}
|
}
|
||||||
b.<!INAPPLICABLE_CANDIDATE{LT}!><!INAPPLICABLE_CANDIDATE{PSI}!>inc<!>()<!>
|
b.<!UNSAFE_CALL{LT}!><!UNSAFE_CALL{PSI}!>inc<!>()<!>
|
||||||
|
|
||||||
if (b == a) {
|
if (b == a) {
|
||||||
b.<!INAPPLICABLE_CANDIDATE{LT}!><!INAPPLICABLE_CANDIDATE{PSI}!>inc<!>()<!>
|
b.<!UNSAFE_CALL{LT}!><!UNSAFE_CALL{PSI}!>inc<!>()<!>
|
||||||
}
|
}
|
||||||
b.<!INAPPLICABLE_CANDIDATE{LT}!><!INAPPLICABLE_CANDIDATE{PSI}!>inc<!>()<!>
|
b.<!UNSAFE_CALL{LT}!><!UNSAFE_CALL{PSI}!>inc<!>()<!>
|
||||||
|
|
||||||
if (b === a) {
|
if (b === a) {
|
||||||
b.<!INAPPLICABLE_CANDIDATE{LT}!><!INAPPLICABLE_CANDIDATE{PSI}!>inc<!>()<!>
|
b.<!UNSAFE_CALL{LT}!><!UNSAFE_CALL{PSI}!>inc<!>()<!>
|
||||||
}
|
}
|
||||||
b.<!INAPPLICABLE_CANDIDATE{LT}!><!INAPPLICABLE_CANDIDATE{PSI}!>inc<!>()<!>
|
b.<!UNSAFE_CALL{LT}!><!UNSAFE_CALL{PSI}!>inc<!>()<!>
|
||||||
}
|
}
|
||||||
|
|
||||||
fun test_11(q: QImpl?, q2: QImpl) {
|
fun test_11(q: QImpl?, q2: QImpl) {
|
||||||
@@ -148,8 +148,8 @@ fun test_11(q: QImpl?, q2: QImpl) {
|
|||||||
// Smartcasting of `q.data` should have no effect on `q2.data`.
|
// Smartcasting of `q.data` should have no effect on `q2.data`.
|
||||||
// Issue: Smartcasting of QImpl.data affects all instances
|
// Issue: Smartcasting of QImpl.data affects all instances
|
||||||
q2.data
|
q2.data
|
||||||
q2.data.<!INAPPLICABLE_CANDIDATE!>s<!> // should be bad
|
q2.data.<!UNSAFE_CALL!>s<!> // should be bad
|
||||||
q2.data.<!INAPPLICABLE_CANDIDATE!>s<!>.inc() // should be bad
|
q2.data.<!UNSAFE_CALL!>s<!>.inc() // should be bad
|
||||||
|
|
||||||
if (q2.data != null) {
|
if (q2.data != null) {
|
||||||
q2.data.s
|
q2.data.s
|
||||||
@@ -162,8 +162,8 @@ fun test_12(q: QImplWithCustomGetter?) {
|
|||||||
// `q.data` is a property that has an open getter, so we can NOT smartcast it to non-nullable MyData.
|
// `q.data` is a property that has an open getter, so we can NOT smartcast it to non-nullable MyData.
|
||||||
if (q?.data?.s?.inc() != null) {
|
if (q?.data?.s?.inc() != null) {
|
||||||
q.data // good
|
q.data // good
|
||||||
q.data.<!INAPPLICABLE_CANDIDATE!>s<!> // should be bad
|
q.data.<!UNSAFE_CALL!>s<!> // should be bad
|
||||||
q.data.<!INAPPLICABLE_CANDIDATE!>s<!>.inc() // should be bad
|
q.data.<!UNSAFE_CALL!>s<!>.inc() // should be bad
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -171,7 +171,7 @@ fun test_13(q: QImplMutable?) {
|
|||||||
// `q.data` is a property that is mutable, so we can NOT smartcast it to non-nullable MyData.
|
// `q.data` is a property that is mutable, so we can NOT smartcast it to non-nullable MyData.
|
||||||
if (q?.data?.s?.inc() != null) {
|
if (q?.data?.s?.inc() != null) {
|
||||||
q.data // good
|
q.data // good
|
||||||
q.data.<!INAPPLICABLE_CANDIDATE!>s<!> // should be bad
|
q.data.<!UNSAFE_CALL!>s<!> // should be bad
|
||||||
q.data.<!INAPPLICABLE_CANDIDATE!>s<!>.inc() // should be bad
|
q.data.<!UNSAFE_CALL!>s<!>.inc() // should be bad
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,6 @@ fun test_3(a: Any?, b: Boolean) {
|
|||||||
|
|
||||||
fun test_4(a: Any?, b: Boolean) {
|
fun test_4(a: Any?, b: Boolean) {
|
||||||
if (a is String || b) {
|
if (a is String || b) {
|
||||||
a.<!INAPPLICABLE_CANDIDATE{LT}!><!INAPPLICABLE_CANDIDATE{PSI}!>foo<!>()<!> // Should be Bad
|
a.<!UNSAFE_CALL{LT}!><!UNSAFE_CALL{PSI}!>foo<!>()<!> // Should be Bad
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
+4
-4
@@ -5,7 +5,7 @@ fun test_1(s: String?) {
|
|||||||
if (s?.check() == true) {
|
if (s?.check() == true) {
|
||||||
s.length // Should be OK
|
s.length // Should be OK
|
||||||
} else {
|
} else {
|
||||||
s.<!INAPPLICABLE_CANDIDATE!>length<!> // Should be bad
|
s.<!UNSAFE_CALL!>length<!> // Should be bad
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -13,13 +13,13 @@ fun test_2(s: String?) {
|
|||||||
if (s?.check() == false) {
|
if (s?.check() == false) {
|
||||||
s.length // Should be OK
|
s.length // Should be OK
|
||||||
} else {
|
} else {
|
||||||
s.<!INAPPLICABLE_CANDIDATE!>length<!> // Should be bad
|
s.<!UNSAFE_CALL!>length<!> // Should be bad
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun test_3(s: String?) {
|
fun test_3(s: String?) {
|
||||||
if (s?.check() != true) {
|
if (s?.check() != true) {
|
||||||
s.<!INAPPLICABLE_CANDIDATE!>length<!> // Should be bad
|
s.<!UNSAFE_CALL!>length<!> // Should be bad
|
||||||
} else {
|
} else {
|
||||||
s.length // Should be OK
|
s.length // Should be OK
|
||||||
}
|
}
|
||||||
@@ -27,7 +27,7 @@ fun test_3(s: String?) {
|
|||||||
|
|
||||||
fun test_4(s: String?) {
|
fun test_4(s: String?) {
|
||||||
if (s?.check() != false) {
|
if (s?.check() != false) {
|
||||||
s.<!INAPPLICABLE_CANDIDATE!>length<!> // Should be bad
|
s.<!UNSAFE_CALL!>length<!> // Should be bad
|
||||||
} else {
|
} else {
|
||||||
s.length // Should be OK
|
s.length // Should be OK
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-3
@@ -5,7 +5,7 @@ fun String.let(block: () -> Unit) {}
|
|||||||
|
|
||||||
fun test(x: String?) {
|
fun test(x: String?) {
|
||||||
x?.foo(x.length == 1)
|
x?.foo(x.length == 1)
|
||||||
x.<!INAPPLICABLE_CANDIDATE!>length<!>
|
x.<!UNSAFE_CALL!>length<!>
|
||||||
}
|
}
|
||||||
|
|
||||||
interface A {
|
interface A {
|
||||||
@@ -27,12 +27,12 @@ fun test_3(x: Any) {
|
|||||||
|
|
||||||
fun test_4(x: A?) {
|
fun test_4(x: A?) {
|
||||||
x?.id()?.bool()
|
x?.id()?.bool()
|
||||||
x.<!INAPPLICABLE_CANDIDATE{LT}!><!INAPPLICABLE_CANDIDATE{PSI}!>id<!>()<!>
|
x.<!UNSAFE_CALL{LT}!><!UNSAFE_CALL{PSI}!>id<!>()<!>
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Any?.boo(b: Boolean) {}
|
fun Any?.boo(b: Boolean) {}
|
||||||
|
|
||||||
fun test_5(x: A?) {
|
fun test_5(x: A?) {
|
||||||
x?.let { return }?.boo(x.bool())
|
x?.let { return }?.boo(x.bool())
|
||||||
x.<!INAPPLICABLE_CANDIDATE{LT}!><!INAPPLICABLE_CANDIDATE{PSI}!>id<!>()<!>
|
x.<!UNSAFE_CALL{LT}!><!UNSAFE_CALL{PSI}!>id<!>()<!>
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -11,5 +11,5 @@ fun test(b: Boolean) {
|
|||||||
} else {
|
} else {
|
||||||
a = null
|
a = null
|
||||||
}
|
}
|
||||||
a.<!INAPPLICABLE_CANDIDATE{LT}!><!INAPPLICABLE_CANDIDATE{PSI}!>foo<!>()<!>
|
a.<!UNSAFE_CALL{LT}!><!UNSAFE_CALL{PSI}!>foo<!>()<!>
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
+1
-1
@@ -18,5 +18,5 @@ fun test_3() {
|
|||||||
x = ""
|
x = ""
|
||||||
x.length
|
x.length
|
||||||
x = null
|
x = null
|
||||||
x.<!INAPPLICABLE_CANDIDATE!>length<!>
|
x.<!UNSAFE_CALL!>length<!>
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
+1
-1
@@ -7,7 +7,7 @@ fun test_1(s: String?) {
|
|||||||
fun test_2(s: String?) {
|
fun test_2(s: String?) {
|
||||||
// contracts related
|
// contracts related
|
||||||
if (s.isNullOrEmpty()) {
|
if (s.isNullOrEmpty()) {
|
||||||
s.<!INAPPLICABLE_CANDIDATE!>length<!> // Should be bad
|
s.<!INAPPLICABLE_CANDIDATE{LT}, UNSAFE_CALL!>length<!> // Should be bad
|
||||||
} else {
|
} else {
|
||||||
s.length // Should be OK
|
s.length // Should be OK
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -21,7 +21,7 @@ fun test_1(x: String?) {
|
|||||||
if (checkNotNull(x)) {
|
if (checkNotNull(x)) {
|
||||||
x.length // OK
|
x.length // OK
|
||||||
} else {
|
} else {
|
||||||
x.<!INAPPLICABLE_CANDIDATE!>length<!> // Error
|
x.<!INAPPLICABLE_CANDIDATE{LT}, UNSAFE_CALL!>length<!> // Error
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -27,7 +27,7 @@ fun test_3(x: A?) {
|
|||||||
with(x) {
|
with(x) {
|
||||||
myRequireNotNull()
|
myRequireNotNull()
|
||||||
}
|
}
|
||||||
x.<!INAPPLICABLE_CANDIDATE!>foo<!>()
|
x.<!INAPPLICABLE_CANDIDATE{LT}, UNSAFE_CALL!>foo<!>()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun test_4(x: A?) {
|
fun test_4(x: A?) {
|
||||||
|
|||||||
+17
-3
@@ -12,6 +12,7 @@ import org.jetbrains.kotlin.fir.analysis.checkers.extended.report
|
|||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirProperty
|
import org.jetbrains.kotlin.fir.declarations.FirProperty
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirValueParameter
|
import org.jetbrains.kotlin.fir.declarations.FirValueParameter
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirVariable
|
import org.jetbrains.kotlin.fir.declarations.FirVariable
|
||||||
import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic
|
import org.jetbrains.kotlin.fir.diagnostics.ConeSimpleDiagnostic
|
||||||
@@ -20,8 +21,12 @@ import org.jetbrains.kotlin.fir.expressions.*
|
|||||||
import org.jetbrains.kotlin.fir.references.FirErrorNamedReference
|
import org.jetbrains.kotlin.fir.references.FirErrorNamedReference
|
||||||
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
|
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
|
||||||
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeAmbiguityError
|
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeAmbiguityError
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeInapplicableCandidateError
|
||||||
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeUnresolvedNameError
|
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeUnresolvedNameError
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol
|
||||||
|
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||||
|
import org.jetbrains.kotlin.fir.types.coneTypeSafe
|
||||||
|
import org.jetbrains.kotlin.fir.types.isNullable
|
||||||
|
|
||||||
object FirDestructuringDeclarationChecker : FirPropertyChecker() {
|
object FirDestructuringDeclarationChecker : FirPropertyChecker() {
|
||||||
override fun check(declaration: FirProperty, context: CheckerContext, reporter: DiagnosticReporter) {
|
override fun check(declaration: FirProperty, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||||
@@ -65,8 +70,8 @@ object FirDestructuringDeclarationChecker : FirPropertyChecker() {
|
|||||||
val originalDestructuringDeclarationOrInitializerSource = originalDestructuringDeclarationOrInitializer.source ?: return
|
val originalDestructuringDeclarationOrInitializerSource = originalDestructuringDeclarationOrInitializer.source ?: return
|
||||||
val originalDestructuringDeclarationType =
|
val originalDestructuringDeclarationType =
|
||||||
when (originalDestructuringDeclarationOrInitializer) {
|
when (originalDestructuringDeclarationOrInitializer) {
|
||||||
is FirVariable<*> -> originalDestructuringDeclarationOrInitializer.returnTypeRef
|
is FirVariable<*> -> originalDestructuringDeclarationOrInitializer.returnTypeRef.coneTypeSafe<ConeKotlinType>()
|
||||||
is FirExpression -> originalDestructuringDeclarationOrInitializer.typeRef
|
is FirExpression -> originalDestructuringDeclarationOrInitializer.typeRef.coneTypeSafe<ConeKotlinType>()
|
||||||
else -> null
|
else -> null
|
||||||
} ?: return
|
} ?: return
|
||||||
|
|
||||||
@@ -89,7 +94,16 @@ object FirDestructuringDeclarationChecker : FirPropertyChecker() {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
// TODO: COMPONENT_FUNCTION_ON_NULLABLE
|
is ConeInapplicableCandidateError -> {
|
||||||
|
if (originalDestructuringDeclarationType.isNullable) {
|
||||||
|
reporter.report(
|
||||||
|
FirErrors.COMPONENT_FUNCTION_ON_NULLABLE.on(
|
||||||
|
originalDestructuringDeclarationOrInitializerSource,
|
||||||
|
(diagnostic.candidateSymbol.fir as FirSimpleFunction).name
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
// TODO: COMPONENT_FUNCTION_RETURN_TYPE_MISMATCH
|
// TODO: COMPONENT_FUNCTION_RETURN_TYPE_MISMATCH
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+27
-6
@@ -10,9 +10,7 @@ import org.jetbrains.kotlin.fir.FirFakeSourceElementKind
|
|||||||
import org.jetbrains.kotlin.fir.FirSourceElement
|
import org.jetbrains.kotlin.fir.FirSourceElement
|
||||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||||
import org.jetbrains.kotlin.fir.analysis.collectors.AbstractDiagnosticCollector
|
import org.jetbrains.kotlin.fir.analysis.collectors.AbstractDiagnosticCollector
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.*
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirDiagnosticFactory0
|
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirErrorFunction
|
import org.jetbrains.kotlin.fir.declarations.FirErrorFunction
|
||||||
import org.jetbrains.kotlin.fir.diagnostics.*
|
import org.jetbrains.kotlin.fir.diagnostics.*
|
||||||
import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind.*
|
import org.jetbrains.kotlin.fir.diagnostics.DiagnosticKind.*
|
||||||
@@ -20,8 +18,9 @@ import org.jetbrains.kotlin.fir.expressions.FirErrorExpression
|
|||||||
import org.jetbrains.kotlin.fir.expressions.FirErrorLoop
|
import org.jetbrains.kotlin.fir.expressions.FirErrorLoop
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirErrorResolvedQualifier
|
import org.jetbrains.kotlin.fir.expressions.FirErrorResolvedQualifier
|
||||||
import org.jetbrains.kotlin.fir.references.FirErrorNamedReference
|
import org.jetbrains.kotlin.fir.references.FirErrorNamedReference
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.calls.InapplicableWrongReceiver
|
||||||
import org.jetbrains.kotlin.fir.resolve.diagnostics.*
|
import org.jetbrains.kotlin.fir.resolve.diagnostics.*
|
||||||
import org.jetbrains.kotlin.fir.types.FirErrorTypeRef
|
import org.jetbrains.kotlin.fir.types.*
|
||||||
import org.jetbrains.kotlin.resolve.calls.tower.isSuccess
|
import org.jetbrains.kotlin.resolve.calls.tower.isSuccess
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||||
|
|
||||||
@@ -62,7 +61,10 @@ class ErrorNodeDiagnosticCollectorComponent(collector: AbstractDiagnosticCollect
|
|||||||
// Will be handled by [FirDestructuringDeclarationChecker]
|
// Will be handled by [FirDestructuringDeclarationChecker]
|
||||||
if (source.elementType == KtNodeTypes.DESTRUCTURING_DECLARATION_ENTRY) {
|
if (source.elementType == KtNodeTypes.DESTRUCTURING_DECLARATION_ENTRY) {
|
||||||
// TODO: if all diagnostics are supported, we don't need the following check, and will bail out based on element type.
|
// TODO: if all diagnostics are supported, we don't need the following check, and will bail out based on element type.
|
||||||
if (diagnostic is ConeUnresolvedNameError || diagnostic is ConeAmbiguityError) {
|
if (diagnostic is ConeUnresolvedNameError ||
|
||||||
|
diagnostic is ConeAmbiguityError ||
|
||||||
|
diagnostic is ConeInapplicableCandidateError
|
||||||
|
) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -72,7 +74,7 @@ class ErrorNodeDiagnosticCollectorComponent(collector: AbstractDiagnosticCollect
|
|||||||
is ConeUnresolvedSymbolError -> FirErrors.UNRESOLVED_REFERENCE.on(source, diagnostic.classId.asString())
|
is ConeUnresolvedSymbolError -> FirErrors.UNRESOLVED_REFERENCE.on(source, diagnostic.classId.asString())
|
||||||
is ConeUnresolvedNameError -> FirErrors.UNRESOLVED_REFERENCE.on(source, diagnostic.name.asString())
|
is ConeUnresolvedNameError -> FirErrors.UNRESOLVED_REFERENCE.on(source, diagnostic.name.asString())
|
||||||
is ConeHiddenCandidateError -> FirErrors.HIDDEN.on(source, diagnostic.candidateSymbol)
|
is ConeHiddenCandidateError -> FirErrors.HIDDEN.on(source, diagnostic.candidateSymbol)
|
||||||
is ConeInapplicableCandidateError -> FirErrors.INAPPLICABLE_CANDIDATE.on(source, diagnostic.candidateSymbol)
|
is ConeInapplicableCandidateError -> mapInapplicableCandidateError(diagnostic, source)
|
||||||
is ConeAmbiguityError -> if (!diagnostic.applicability.isSuccess) {
|
is ConeAmbiguityError -> if (!diagnostic.applicability.isSuccess) {
|
||||||
FirErrors.NONE_APPLICABLE.on(source, diagnostic.candidates)
|
FirErrors.NONE_APPLICABLE.on(source, diagnostic.candidates)
|
||||||
} else {
|
} else {
|
||||||
@@ -98,6 +100,25 @@ class ErrorNodeDiagnosticCollectorComponent(collector: AbstractDiagnosticCollect
|
|||||||
reporter.report(coneDiagnostic)
|
reporter.report(coneDiagnostic)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun mapInapplicableCandidateError(
|
||||||
|
diagnostic: ConeInapplicableCandidateError,
|
||||||
|
source: FirSourceElement,
|
||||||
|
): FirDiagnostic<*> {
|
||||||
|
// TODO: Need to distinguish SMARTCAST_IMPOSSIBLE
|
||||||
|
// TODO: handle other UNSAFE_* variants: invoke, infix, operator
|
||||||
|
val rootCause = diagnostic.diagnostics.find { it.applicability == diagnostic.applicability }
|
||||||
|
return if (rootCause != null &&
|
||||||
|
rootCause is InapplicableWrongReceiver &&
|
||||||
|
rootCause.actualType?.isNullable == true &&
|
||||||
|
(rootCause.expectedType == null || !rootCause.expectedType!!.isMarkedNullable)
|
||||||
|
) {
|
||||||
|
// TODO: report on call operation node, e.g., x<!>.<!>length instead of x.<!>length<!>
|
||||||
|
FirErrors.UNSAFE_CALL.on(source, rootCause.actualType!!)
|
||||||
|
} else {
|
||||||
|
FirErrors.INAPPLICABLE_CANDIDATE.on(source, diagnostic.candidateSymbol)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun ConeSimpleDiagnostic.getFactory(): FirDiagnosticFactory0<FirSourceElement, *> {
|
private fun ConeSimpleDiagnostic.getFactory(): FirDiagnosticFactory0<FirSourceElement, *> {
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
return when (kind) {
|
return when (kind) {
|
||||||
|
|||||||
+19
@@ -37,6 +37,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CAN_BE_VAL
|
|||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CLASS_IN_SUPERTYPE_FOR_ENUM
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CLASS_IN_SUPERTYPE_FOR_ENUM
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.COMPONENT_FUNCTION_AMBIGUITY
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.COMPONENT_FUNCTION_AMBIGUITY
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.COMPONENT_FUNCTION_MISSING
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.COMPONENT_FUNCTION_MISSING
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.COMPONENT_FUNCTION_ON_NULLABLE
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CONFLICTING_OVERLOADS
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CONFLICTING_OVERLOADS
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CONFLICTING_PROJECTION
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CONFLICTING_PROJECTION
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CONSTRUCTOR_IN_INTERFACE
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CONSTRUCTOR_IN_INTERFACE
|
||||||
@@ -137,6 +138,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.TYPE_PARAMETER_AS
|
|||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.UNINITIALIZED_VARIABLE
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.UNINITIALIZED_VARIABLE
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.UNRESOLVED_LABEL
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.UNRESOLVED_LABEL
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.UNRESOLVED_REFERENCE
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.UNRESOLVED_REFERENCE
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.UNSAFE_CALL
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.UNUSED_VARIABLE
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.UNUSED_VARIABLE
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.UPPER_BOUND_VIOLATED
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.UPPER_BOUND_VIOLATED
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.USELESS_VARARG_ON_PARAMETER
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.USELESS_VARARG_ON_PARAMETER
|
||||||
@@ -418,6 +420,11 @@ class FirDefaultErrorMessages : DefaultErrorMessages.Extension {
|
|||||||
TO_STRING,
|
TO_STRING,
|
||||||
AMBIGUOUS_CALLS
|
AMBIGUOUS_CALLS
|
||||||
)
|
)
|
||||||
|
map.put(
|
||||||
|
COMPONENT_FUNCTION_ON_NULLABLE,
|
||||||
|
"Not nullable value required to call ''{0}()'' function of destructuring declaration initializer",
|
||||||
|
TO_STRING
|
||||||
|
)
|
||||||
|
|
||||||
// Control flow diagnostics
|
// Control flow diagnostics
|
||||||
map.put(UNINITIALIZED_VARIABLE, "{0} must be initialized before access", PROPERTY_NAME)
|
map.put(UNINITIALIZED_VARIABLE, "{0} must be initialized before access", PROPERTY_NAME)
|
||||||
@@ -431,6 +438,18 @@ class FirDefaultErrorMessages : DefaultErrorMessages.Extension {
|
|||||||
map.put(LEAKED_IN_PLACE_LAMBDA, "Leaked in-place lambda: {2}", SYMBOL)
|
map.put(LEAKED_IN_PLACE_LAMBDA, "Leaked in-place lambda: {2}", SYMBOL)
|
||||||
map.put(FirErrors.WRONG_IMPLIES_CONDITION, "Wrong implies condition")
|
map.put(FirErrors.WRONG_IMPLIES_CONDITION, "Wrong implies condition")
|
||||||
|
|
||||||
|
// Nullability
|
||||||
|
map.put(
|
||||||
|
UNSAFE_CALL,
|
||||||
|
"Only safe (?.) or non-null asserted (!!.) calls are allowed on a nullable receiver of type {0}",
|
||||||
|
RENDER_TYPE
|
||||||
|
)
|
||||||
|
//map.put(
|
||||||
|
// UNSAFE_IMPLICIT_INVOKE_CALL,
|
||||||
|
// "Reference has a nullable type ''{0}'', use explicit \"?.invoke\" to make a function-like call instead.",
|
||||||
|
// RENDER_TYPE
|
||||||
|
//)
|
||||||
|
|
||||||
// Extended checkers group
|
// Extended checkers group
|
||||||
map.put(REDUNDANT_VISIBILITY_MODIFIER, "Redundant visibility modifier")
|
map.put(REDUNDANT_VISIBILITY_MODIFIER, "Redundant visibility modifier")
|
||||||
map.put(REDUNDANT_MODALITY_MODIFIER, "Redundant modality modifier")
|
map.put(REDUNDANT_MODALITY_MODIFIER, "Redundant modality modifier")
|
||||||
|
|||||||
+4
-3
@@ -13,7 +13,8 @@ import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
|
|||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
|
||||||
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||||
|
import org.jetbrains.kotlin.fir.types.render
|
||||||
|
|
||||||
object FirDiagnosticRenderers {
|
object FirDiagnosticRenderers {
|
||||||
val NULLABLE_STRING = Renderer<String?> { it ?: "null" }
|
val NULLABLE_STRING = Renderer<String?> { it ?: "null" }
|
||||||
@@ -58,9 +59,9 @@ object FirDiagnosticRenderers {
|
|||||||
name.asString()
|
name.asString()
|
||||||
}
|
}
|
||||||
|
|
||||||
val RENDER_TYPE = Renderer { typeRef: FirTypeRef ->
|
val RENDER_TYPE = Renderer { t: ConeKotlinType ->
|
||||||
// TODO: need a way to tune granuality, e.g., without parameter names in functional types.
|
// TODO: need a way to tune granuality, e.g., without parameter names in functional types.
|
||||||
typeRef.render()
|
t.render()
|
||||||
}
|
}
|
||||||
|
|
||||||
val AMBIGUOUS_CALLS = Renderer { candidates: Collection<AbstractFirBasedSymbol<*>> ->
|
val AMBIGUOUS_CALLS = Renderer { candidates: Collection<AbstractFirBasedSymbol<*>> ->
|
||||||
|
|||||||
+10
-3
@@ -197,9 +197,9 @@ object FirErrors {
|
|||||||
|
|
||||||
// Destructuring declaration
|
// Destructuring declaration
|
||||||
val INITIALIZER_REQUIRED_FOR_DESTRUCTURING_DECLARATION by error0<FirSourceElement, KtDestructuringDeclaration>()
|
val INITIALIZER_REQUIRED_FOR_DESTRUCTURING_DECLARATION by error0<FirSourceElement, KtDestructuringDeclaration>()
|
||||||
val COMPONENT_FUNCTION_MISSING by error2<FirSourceElement, PsiElement, Name, FirTypeRef>()
|
val COMPONENT_FUNCTION_MISSING by error2<FirSourceElement, KtExpression, Name, ConeKotlinType>()
|
||||||
val COMPONENT_FUNCTION_AMBIGUITY by error2<FirSourceElement, PsiElement, Name, Collection<AbstractFirBasedSymbol<*>>>()
|
val COMPONENT_FUNCTION_AMBIGUITY by error2<FirSourceElement, KtExpression, Name, Collection<AbstractFirBasedSymbol<*>>>()
|
||||||
// TODO: val COMPONENT_FUNCTION_ON_NULLABLE by ...
|
val COMPONENT_FUNCTION_ON_NULLABLE by error1<FirSourceElement, KtExpression, Name>()
|
||||||
// TODO: val COMPONENT_FUNCTION_RETURN_TYPE_MISMATCH by ...
|
// TODO: val COMPONENT_FUNCTION_RETURN_TYPE_MISMATCH by ...
|
||||||
|
|
||||||
// Control flow diagnostics
|
// Control flow diagnostics
|
||||||
@@ -208,6 +208,13 @@ object FirErrors {
|
|||||||
val LEAKED_IN_PLACE_LAMBDA by error1<FirSourceElement, PsiElement, AbstractFirBasedSymbol<*>>()
|
val LEAKED_IN_PLACE_LAMBDA by error1<FirSourceElement, PsiElement, AbstractFirBasedSymbol<*>>()
|
||||||
val WRONG_IMPLIES_CONDITION by warning0<FirSourceElement, PsiElement>()
|
val WRONG_IMPLIES_CONDITION by warning0<FirSourceElement, PsiElement>()
|
||||||
|
|
||||||
|
// Nullability
|
||||||
|
val UNSAFE_CALL by error1<FirSourceElement, PsiElement, ConeKotlinType>()
|
||||||
|
// TODO: val UNSAFE_IMPLICIT_INVOKE_CALL by error1<FirSourceElement, PsiElement, ConeKotlinType>()
|
||||||
|
// TODO: val UNSAFE_INFIX_CALL by ...
|
||||||
|
// TODO: val UNSAFE_OPERATOR_CALL by ...
|
||||||
|
// TODO: val UNEXPECTED_SAFE_CALL by ...
|
||||||
|
|
||||||
// Extended checkers group
|
// Extended checkers group
|
||||||
val REDUNDANT_VISIBILITY_MODIFIER by warning0<FirSourceElement, KtModifierListOwner>(SourceElementPositioningStrategies.VISIBILITY_MODIFIER)
|
val REDUNDANT_VISIBILITY_MODIFIER by warning0<FirSourceElement, KtModifierListOwner>(SourceElementPositioningStrategies.VISIBILITY_MODIFIER)
|
||||||
val REDUNDANT_MODALITY_MODIFIER by warning0<FirSourceElement, KtModifierListOwner>(SourceElementPositioningStrategies.MODALITY_MODIFIER)
|
val REDUNDANT_MODALITY_MODIFIER by warning0<FirSourceElement, KtModifierListOwner>(SourceElementPositioningStrategies.MODALITY_MODIFIER)
|
||||||
|
|||||||
@@ -310,7 +310,7 @@ private fun checkApplicabilityForArgumentType(
|
|||||||
if (expectedType == null) return
|
if (expectedType == null) return
|
||||||
if (isReceiver && isDispatch) {
|
if (isReceiver && isDispatch) {
|
||||||
if (!expectedType.isNullable && argumentType.isMarkedNullable) {
|
if (!expectedType.isNullable && argumentType.isMarkedNullable) {
|
||||||
sink.reportDiagnostic(InapplicableWrongReceiver)
|
sink.reportDiagnostic(InapplicableWrongReceiver(expectedType, argumentType))
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -323,10 +323,10 @@ private fun checkApplicabilityForArgumentType(
|
|||||||
val nullableExpectedType = expectedType.withNullability(ConeNullability.NULLABLE, context.session.typeContext)
|
val nullableExpectedType = expectedType.withNullability(ConeNullability.NULLABLE, context.session.typeContext)
|
||||||
|
|
||||||
if (csBuilder.addSubtypeConstraintIfCompatible(argumentType, nullableExpectedType, position)) {
|
if (csBuilder.addSubtypeConstraintIfCompatible(argumentType, nullableExpectedType, position)) {
|
||||||
sink.reportDiagnostic(InapplicableWrongReceiver) // TODO
|
sink.reportDiagnostic(InapplicableWrongReceiver(expectedType, argumentType)) // TODO
|
||||||
} else {
|
} else {
|
||||||
csBuilder.addSubtypeConstraint(argumentType, expectedType, position)
|
csBuilder.addSubtypeConstraint(argumentType, expectedType, position)
|
||||||
sink.reportDiagnostic(InapplicableWrongReceiver)
|
sink.reportDiagnostic(InapplicableWrongReceiver(expectedType, argumentType))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-1
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.fir.resolve.calls
|
|||||||
import org.jetbrains.kotlin.fir.declarations.FirFunction
|
import org.jetbrains.kotlin.fir.declarations.FirFunction
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirValueParameter
|
import org.jetbrains.kotlin.fir.declarations.FirValueParameter
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
||||||
|
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||||
import org.jetbrains.kotlin.resolve.calls.tower.CandidateApplicability
|
import org.jetbrains.kotlin.resolve.calls.tower.CandidateApplicability
|
||||||
|
|
||||||
abstract class ResolutionDiagnostic(val applicability: CandidateApplicability)
|
abstract class ResolutionDiagnostic(val applicability: CandidateApplicability)
|
||||||
@@ -57,7 +58,10 @@ object HiddenCandidate : ResolutionDiagnostic(CandidateApplicability.HIDDEN)
|
|||||||
|
|
||||||
object ResolvedWithLowPriority : ResolutionDiagnostic(CandidateApplicability.RESOLVED_LOW_PRIORITY)
|
object ResolvedWithLowPriority : ResolutionDiagnostic(CandidateApplicability.RESOLVED_LOW_PRIORITY)
|
||||||
|
|
||||||
object InapplicableWrongReceiver : ResolutionDiagnostic(CandidateApplicability.INAPPLICABLE_WRONG_RECEIVER)
|
class InapplicableWrongReceiver(
|
||||||
|
val expectedType: ConeKotlinType? = null,
|
||||||
|
val actualType: ConeKotlinType? = null,
|
||||||
|
) : ResolutionDiagnostic(CandidateApplicability.INAPPLICABLE_WRONG_RECEIVER)
|
||||||
|
|
||||||
object LowerPriorityToPreserveCompatibilityDiagnostic : ResolutionDiagnostic(CandidateApplicability.RESOLVED_NEED_PRESERVE_COMPATIBILITY)
|
object LowerPriorityToPreserveCompatibilityDiagnostic : ResolutionDiagnostic(CandidateApplicability.RESOLVED_NEED_PRESERVE_COMPATIBILITY)
|
||||||
|
|
||||||
|
|||||||
@@ -39,17 +39,17 @@ internal object CheckExplicitReceiverConsistency : ResolutionStage() {
|
|||||||
when (receiverKind) {
|
when (receiverKind) {
|
||||||
NO_EXPLICIT_RECEIVER -> {
|
NO_EXPLICIT_RECEIVER -> {
|
||||||
if (explicitReceiver != null && explicitReceiver !is FirResolvedQualifier && !explicitReceiver.isSuperReferenceExpression()) {
|
if (explicitReceiver != null && explicitReceiver !is FirResolvedQualifier && !explicitReceiver.isSuperReferenceExpression()) {
|
||||||
return sink.yieldDiagnostic(InapplicableWrongReceiver)
|
return sink.yieldDiagnostic(InapplicableWrongReceiver(actualType = explicitReceiver.typeRef.coneTypeSafe()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
EXTENSION_RECEIVER, DISPATCH_RECEIVER -> {
|
EXTENSION_RECEIVER, DISPATCH_RECEIVER -> {
|
||||||
if (explicitReceiver == null) {
|
if (explicitReceiver == null) {
|
||||||
return sink.yieldDiagnostic(InapplicableWrongReceiver)
|
return sink.yieldDiagnostic(InapplicableWrongReceiver())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
BOTH_RECEIVERS -> {
|
BOTH_RECEIVERS -> {
|
||||||
if (explicitReceiver == null) {
|
if (explicitReceiver == null) {
|
||||||
return sink.yieldDiagnostic(InapplicableWrongReceiver)
|
return sink.yieldDiagnostic(InapplicableWrongReceiver())
|
||||||
}
|
}
|
||||||
// Here we should also check additional invoke receiver
|
// Here we should also check additional invoke receiver
|
||||||
}
|
}
|
||||||
@@ -105,7 +105,7 @@ object CheckDispatchReceiver : ResolutionStage() {
|
|||||||
val dispatchReceiverValueType = candidate.dispatchReceiverValue?.type ?: return
|
val dispatchReceiverValueType = candidate.dispatchReceiverValue?.type ?: return
|
||||||
|
|
||||||
if (!AbstractNullabilityChecker.isSubtypeOfAny(context.session.typeContext, dispatchReceiverValueType)) {
|
if (!AbstractNullabilityChecker.isSubtypeOfAny(context.session.typeContext, dispatchReceiverValueType)) {
|
||||||
sink.yieldDiagnostic(InapplicableWrongReceiver)
|
sink.yieldDiagnostic(InapplicableWrongReceiver(actualType = dispatchReceiverValueType))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-1
@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration
|
|||||||
import org.jetbrains.kotlin.fir.diagnostics.ConeDiagnostic
|
import org.jetbrains.kotlin.fir.diagnostics.ConeDiagnostic
|
||||||
import org.jetbrains.kotlin.fir.render
|
import org.jetbrains.kotlin.fir.render
|
||||||
import org.jetbrains.kotlin.fir.resolve.calls.Candidate
|
import org.jetbrains.kotlin.fir.resolve.calls.Candidate
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.calls.ResolutionDiagnostic
|
||||||
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
|
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
|
||||||
@@ -37,14 +38,16 @@ class ConeHiddenCandidateError(
|
|||||||
override val reason: String get() = "HIDDEN: ${describeSymbol(candidateSymbol)} is invisible"
|
override val reason: String get() = "HIDDEN: ${describeSymbol(candidateSymbol)} is invisible"
|
||||||
}
|
}
|
||||||
|
|
||||||
class ConeInapplicableCandidateError(
|
class ConeInapplicableCandidateError private constructor(
|
||||||
val applicability: CandidateApplicability,
|
val applicability: CandidateApplicability,
|
||||||
val candidateSymbol: AbstractFirBasedSymbol<*>,
|
val candidateSymbol: AbstractFirBasedSymbol<*>,
|
||||||
|
val diagnostics: List<ResolutionDiagnostic>,
|
||||||
val errors: List<ConstraintSystemError>
|
val errors: List<ConstraintSystemError>
|
||||||
) : ConeDiagnostic() {
|
) : ConeDiagnostic() {
|
||||||
constructor(applicability: CandidateApplicability, candidate: Candidate) : this(
|
constructor(applicability: CandidateApplicability, candidate: Candidate) : this(
|
||||||
applicability,
|
applicability,
|
||||||
candidate.symbol,
|
candidate.symbol,
|
||||||
|
candidate.diagnostics,
|
||||||
candidate.system.errors
|
candidate.system.errors
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ class C {
|
|||||||
while (a == null) {
|
while (a == null) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
a.<!INAPPLICABLE_CANDIDATE!>compareTo<!>("2")
|
a.<!UNSAFE_CALL!>compareTo<!>("2")
|
||||||
}
|
}
|
||||||
|
|
||||||
fun notContainsBreak(a: String?, b: String?) {
|
fun notContainsBreak(a: String?, b: String?) {
|
||||||
@@ -70,7 +70,7 @@ class C {
|
|||||||
break@l
|
break@l
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
a.<!INAPPLICABLE_CANDIDATE!>compareTo<!>("2")
|
a.<!UNSAFE_CALL!>compareTo<!>("2")
|
||||||
}
|
}
|
||||||
|
|
||||||
fun unresolvedBreak(a: String?, array: Array<Int>) {
|
fun unresolvedBreak(a: String?, array: Array<Int>) {
|
||||||
@@ -80,7 +80,7 @@ class C {
|
|||||||
}
|
}
|
||||||
if (true) break else <!NOT_A_LOOP_LABEL!>break@l<!>
|
if (true) break else <!NOT_A_LOOP_LABEL!>break@l<!>
|
||||||
}
|
}
|
||||||
a.<!INAPPLICABLE_CANDIDATE!>compareTo<!>("2")
|
a.<!UNSAFE_CALL!>compareTo<!>("2")
|
||||||
}
|
}
|
||||||
|
|
||||||
fun twoLabelsOnLoop() {
|
fun twoLabelsOnLoop() {
|
||||||
|
|||||||
+1
-1
@@ -158,7 +158,7 @@ fun test() {
|
|||||||
|
|
||||||
fun f(out : String?) {
|
fun f(out : String?) {
|
||||||
out?.get(0)
|
out?.get(0)
|
||||||
out.<!INAPPLICABLE_CANDIDATE!>get<!>(0)
|
out.<!UNSAFE_CALL!>get<!>(0)
|
||||||
if (out != null) else return;
|
if (out != null) else return;
|
||||||
out.get(0)
|
out.get(0)
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-4
@@ -14,11 +14,11 @@ fun test() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun check() {
|
fun check() {
|
||||||
[1, 2] <!INAPPLICABLE_CANDIDATE!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><Array<Int>>() }
|
[1, 2] <!UNSAFE_CALL!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><Array<Int>>() }
|
||||||
[""] <!INAPPLICABLE_CANDIDATE!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><Array<String>>() }
|
[""] <!UNSAFE_CALL!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><Array<String>>() }
|
||||||
|
|
||||||
val f: IntArray = [1]
|
val f: IntArray = [1]
|
||||||
[f] <!INAPPLICABLE_CANDIDATE!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><Array<IntArray>>() }
|
[f] <!UNSAFE_CALL!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><Array<IntArray>>() }
|
||||||
|
|
||||||
[1, ""] <!INAPPLICABLE_CANDIDATE!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><Array<Any>>() }
|
[1, ""] <!UNSAFE_CALL!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><Array<Any>>() }
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
+3
-3
@@ -7,9 +7,9 @@ operator fun <K> Container<K>.iterator(): Iterator<K> = null!!
|
|||||||
fun test() {
|
fun test() {
|
||||||
val container: Container<String>? = null
|
val container: Container<String>? = null
|
||||||
// Error
|
// Error
|
||||||
container.<!INAPPLICABLE_CANDIDATE!>iterator<!>()
|
container.<!UNSAFE_CALL!>iterator<!>()
|
||||||
// for extension iterator, this code compiles, but should not
|
// for extension iterator, this code compiles, but should not
|
||||||
<!INAPPLICABLE_CANDIDATE!>for (s in container) {}<!>
|
<!UNSAFE_CALL!>for (s in container) {}<!>
|
||||||
}
|
}
|
||||||
class OtherContainer<K>(val k: K) {
|
class OtherContainer<K>(val k: K) {
|
||||||
operator fun iterator(): Iterator<K> = null!!
|
operator fun iterator(): Iterator<K> = null!!
|
||||||
@@ -18,5 +18,5 @@ class OtherContainer<K>(val k: K) {
|
|||||||
fun test2() {
|
fun test2() {
|
||||||
val other: OtherContainer<String>? = null
|
val other: OtherContainer<String>? = null
|
||||||
// Error
|
// Error
|
||||||
<!INAPPLICABLE_CANDIDATE!>for (s in other) {}<!>
|
<!UNSAFE_CALL!>for (s in other) {}<!>
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -8,7 +8,7 @@ class It {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun test(c: Coll?) {
|
fun test(c: Coll?) {
|
||||||
<!INAPPLICABLE_CANDIDATE!>for (x in c) {}<!>
|
<!UNSAFE_CALL!>for (x in c) {}<!>
|
||||||
|
|
||||||
if (c != null) {
|
if (c != null) {
|
||||||
for(x in c) {}
|
for(x in c) {}
|
||||||
|
|||||||
+1
-1
@@ -8,5 +8,5 @@ class It {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun test() {
|
fun test() {
|
||||||
<!INAPPLICABLE_CANDIDATE, INAPPLICABLE_CANDIDATE!>for (x in Coll()) {}<!>
|
<!UNSAFE_CALL, UNSAFE_CALL!>for (x in Coll()) {}<!>
|
||||||
}
|
}
|
||||||
+2
-2
@@ -8,7 +8,7 @@ operator fun <T> Data<T>.component2() = y
|
|||||||
fun foo(): Int {
|
fun foo(): Int {
|
||||||
val d: Data<Int>? = null
|
val d: Data<Int>? = null
|
||||||
// An error must be here
|
// An error must be here
|
||||||
val (<!INAPPLICABLE_CANDIDATE!>x<!>, <!INAPPLICABLE_CANDIDATE!>y<!>) = d
|
val (x, y) = <!COMPONENT_FUNCTION_ON_NULLABLE, COMPONENT_FUNCTION_ON_NULLABLE!>d<!>
|
||||||
return x + y
|
return x + y
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -17,6 +17,6 @@ data class NormalData<T>(val x: T, val y: T)
|
|||||||
fun bar(): Int {
|
fun bar(): Int {
|
||||||
val d: NormalData<Int>? = null
|
val d: NormalData<Int>? = null
|
||||||
// An error must be here
|
// An error must be here
|
||||||
val (<!INAPPLICABLE_CANDIDATE!>x<!>, <!INAPPLICABLE_CANDIDATE!>y<!>) = d
|
val (x, y) = <!COMPONENT_FUNCTION_ON_NULLABLE, COMPONENT_FUNCTION_ON_NULLABLE!>d<!>
|
||||||
return x + y
|
return x + y
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -10,6 +10,6 @@ fun test(a: Any?, flag: Boolean, x: Any?) {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
b = x
|
b = x
|
||||||
b.<!INAPPLICABLE_CANDIDATE!>hashCode<!>()
|
b.<!UNSAFE_CALL!>hashCode<!>()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+3
-3
@@ -4,11 +4,11 @@ fun baz(b: Boolean): Boolean = !b
|
|||||||
fun foo() {
|
fun foo() {
|
||||||
val x: Int? = null
|
val x: Int? = null
|
||||||
|
|
||||||
bar(<!INAPPLICABLE_CANDIDATE!>-<!>x)
|
bar(<!UNSAFE_CALL!>-<!>x)
|
||||||
if (x != null) bar(-x)
|
if (x != null) bar(-x)
|
||||||
bar(<!INAPPLICABLE_CANDIDATE!>-<!>x)
|
bar(<!UNSAFE_CALL!>-<!>x)
|
||||||
|
|
||||||
val b: Boolean? = null
|
val b: Boolean? = null
|
||||||
baz(<!INAPPLICABLE_CANDIDATE!>!<!>b)
|
baz(<!UNSAFE_CALL!>!<!>b)
|
||||||
if (b != null) baz(!b)
|
if (b != null) baz(!b)
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -11,7 +11,7 @@ class MyClass2 {}
|
|||||||
<!CONFLICTING_OVERLOADS!>fun MyClass2.component1()<!> = 1.3
|
<!CONFLICTING_OVERLOADS!>fun MyClass2.component1()<!> = 1.3
|
||||||
|
|
||||||
fun test(mc1: MyClass, mc2: MyClass2) {
|
fun test(mc1: MyClass, mc2: MyClass2) {
|
||||||
val (<!INAPPLICABLE_CANDIDATE!>a<!>, b) = <!COMPONENT_FUNCTION_MISSING!>mc1<!>
|
val (a, b) = <!COMPONENT_FUNCTION_MISSING!>mc1<!>
|
||||||
val (c) = mc2
|
val (c) = mc2
|
||||||
|
|
||||||
//a,b,c are error types
|
//a,b,c are error types
|
||||||
|
|||||||
Vendored
+1
-1
@@ -5,7 +5,7 @@ fun foo(block: () -> (() -> Int)) {}
|
|||||||
|
|
||||||
fun test() {
|
fun test() {
|
||||||
val x = <!EXPRESSION_REQUIRED!>fun named1(x: Int): Int { return 1 }<!>
|
val x = <!EXPRESSION_REQUIRED!>fun named1(x: Int): Int { return 1 }<!>
|
||||||
x <!INAPPLICABLE_CANDIDATE!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><Function1<Int, Int>>() }
|
x <!UNSAFE_CALL!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><Function1<Int, Int>>() }
|
||||||
|
|
||||||
foo { fun named2(): Int {return 1} }
|
foo { fun named2(): Int {return 1} }
|
||||||
foo({ fun named3() = 1 })
|
foo({ fun named3() = 1 })
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ import outer.*
|
|||||||
|
|
||||||
command.foo
|
command.foo
|
||||||
|
|
||||||
command.<!INAPPLICABLE_CANDIDATE!>equals<!>(null)
|
command.<!UNSAFE_CALL!>equals<!>(null)
|
||||||
command?.equals(null)
|
command?.equals(null)
|
||||||
command.equals1(null)
|
command.equals1(null)
|
||||||
command?.equals1(null)
|
command?.equals1(null)
|
||||||
|
|||||||
@@ -9,13 +9,13 @@ interface T {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun test(t: T) {
|
fun test(t: T) {
|
||||||
t.<!INAPPLICABLE_CANDIDATE!>f<!>(1) //unsafe call error
|
t.<!UNSAFE_CALL!>f<!>(1) //unsafe call error
|
||||||
t.f?.invoke(1)
|
t.f?.invoke(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun test1(t: T?) {
|
fun test1(t: T?) {
|
||||||
t.<!UNRESOLVED_REFERENCE!>f<!>(1) // todo resolve f as value and report UNSAFE_CALL
|
t.<!UNRESOLVED_REFERENCE!>f<!>(1) // todo resolve f as value and report UNSAFE_CALL
|
||||||
t?.<!INAPPLICABLE_CANDIDATE!>f<!>(1)
|
t?.<!UNSAFE_CALL!>f<!>(1)
|
||||||
t.<!INAPPLICABLE_CANDIDATE!>f<!>?.invoke(1)
|
t.<!UNSAFE_CALL!>f<!>?.invoke(1)
|
||||||
t?.f?.invoke(1)
|
t?.f?.invoke(1)
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-3
@@ -8,7 +8,7 @@ fun <R> List<R>.a() {}
|
|||||||
|
|
||||||
fun test1(i: Int?) {
|
fun test1(i: Int?) {
|
||||||
1.<!INAPPLICABLE_CANDIDATE!>a<!>()
|
1.<!INAPPLICABLE_CANDIDATE!>a<!>()
|
||||||
i.<!INAPPLICABLE_CANDIDATE!>a<!>()
|
i.<!UNSAFE_CALL!>a<!>()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun <R> test2(c: Collection<R>) {
|
fun <R> test2(c: Collection<R>) {
|
||||||
@@ -19,7 +19,7 @@ fun Int.foo() {}
|
|||||||
|
|
||||||
fun test3(s: String?) {
|
fun test3(s: String?) {
|
||||||
"".<!INAPPLICABLE_CANDIDATE!>foo<!>()
|
"".<!INAPPLICABLE_CANDIDATE!>foo<!>()
|
||||||
s.<!INAPPLICABLE_CANDIDATE!>foo<!>()
|
s.<!UNSAFE_CALL!>foo<!>()
|
||||||
"".<!INAPPLICABLE_CANDIDATE!>foo<!>(1)
|
"".<!INAPPLICABLE_CANDIDATE!>foo<!>(1)
|
||||||
s.<!INAPPLICABLE_CANDIDATE!>foo<!>("a")
|
s.<!INAPPLICABLE_CANDIDATE!>foo<!>("a")
|
||||||
}
|
}
|
||||||
@@ -52,5 +52,5 @@ fun test7(l: List<String?>) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun test8(l: List<Any>?) {
|
fun test8(l: List<Any>?) {
|
||||||
l.<!INAPPLICABLE_CANDIDATE!>b<!>()
|
l.<!UNSAFE_CALL!>b<!>()
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
+6
-6
@@ -24,24 +24,24 @@ fun bar(aInstance: A, bInstance: B) {
|
|||||||
|
|
||||||
foo(bInstance) {
|
foo(bInstance) {
|
||||||
(a, b): A, (c, d) ->
|
(a, b): A, (c, d) ->
|
||||||
<!UNRESOLVED_REFERENCE!>a<!> <!INAPPLICABLE_CANDIDATE!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><Int>() }
|
<!UNRESOLVED_REFERENCE!>a<!> <!UNSAFE_CALL!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><Int>() }
|
||||||
<!UNRESOLVED_REFERENCE!>b<!> <!INAPPLICABLE_CANDIDATE!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><String>() }
|
<!UNRESOLVED_REFERENCE!>b<!> <!UNSAFE_CALL!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><String>() }
|
||||||
c checkType { _<Double>() }
|
c checkType { _<Double>() }
|
||||||
d checkType { _<Short>() }
|
d checkType { _<Short>() }
|
||||||
}
|
}
|
||||||
|
|
||||||
foo(bInstance) {
|
foo(bInstance) {
|
||||||
(a, b), (c, d) ->
|
(a, b), (c, d) ->
|
||||||
<!UNRESOLVED_REFERENCE!>a<!> <!INAPPLICABLE_CANDIDATE!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><Int>() }
|
<!UNRESOLVED_REFERENCE!>a<!> <!UNSAFE_CALL!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><Int>() }
|
||||||
<!UNRESOLVED_REFERENCE!>b<!> <!INAPPLICABLE_CANDIDATE!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><String>() }
|
<!UNRESOLVED_REFERENCE!>b<!> <!UNSAFE_CALL!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><String>() }
|
||||||
c checkType { _<Double>() }
|
c checkType { _<Double>() }
|
||||||
d checkType { _<Short>() }
|
d checkType { _<Short>() }
|
||||||
}
|
}
|
||||||
|
|
||||||
foo<A, B>(bInstance) {
|
foo<A, B>(bInstance) {
|
||||||
(a, b), (c, d) ->
|
(a, b), (c, d) ->
|
||||||
<!UNRESOLVED_REFERENCE!>a<!> <!INAPPLICABLE_CANDIDATE!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><Int>() }
|
<!UNRESOLVED_REFERENCE!>a<!> <!UNSAFE_CALL!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><Int>() }
|
||||||
<!UNRESOLVED_REFERENCE!>b<!> <!INAPPLICABLE_CANDIDATE!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><String>() }
|
<!UNRESOLVED_REFERENCE!>b<!> <!UNSAFE_CALL!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><String>() }
|
||||||
c checkType { _<Double>() }
|
c checkType { _<Double>() }
|
||||||
d checkType { _<Short>() }
|
d checkType { _<Short>() }
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
+1
-1
@@ -23,7 +23,7 @@ fun bar() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
foo { (a, b), (c, b) ->
|
foo { (a, b), (c, b) ->
|
||||||
<!UNRESOLVED_REFERENCE!>a<!> <!INAPPLICABLE_CANDIDATE!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><Int>() }
|
<!UNRESOLVED_REFERENCE!>a<!> <!UNSAFE_CALL!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><Int>() }
|
||||||
b checkType { <!INAPPLICABLE_CANDIDATE!>_<!><String>() }
|
b checkType { <!INAPPLICABLE_CANDIDATE!>_<!><String>() }
|
||||||
c checkType { <!INAPPLICABLE_CANDIDATE!>_<!><B>() }
|
c checkType { <!INAPPLICABLE_CANDIDATE!>_<!><B>() }
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -36,8 +36,8 @@ fun bar() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
foobar { (a, b), (c, d) ->
|
foobar { (a, b), (c, d) ->
|
||||||
<!UNRESOLVED_REFERENCE!>a<!> <!INAPPLICABLE_CANDIDATE!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><Int>() }
|
<!UNRESOLVED_REFERENCE!>a<!> <!UNSAFE_CALL!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><Int>() }
|
||||||
<!UNRESOLVED_REFERENCE!>b<!> <!INAPPLICABLE_CANDIDATE!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><String>() }
|
<!UNRESOLVED_REFERENCE!>b<!> <!UNSAFE_CALL!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><String>() }
|
||||||
c checkType { _<Double>() }
|
c checkType { _<Double>() }
|
||||||
d checkType { _<Short>() }
|
d checkType { _<Short>() }
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
+2
-2
@@ -32,12 +32,12 @@ fun bar() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
foobar { (a, b), (c, d) ->
|
foobar { (a, b), (c, d) ->
|
||||||
<!UNRESOLVED_REFERENCE!>a<!> <!INAPPLICABLE_CANDIDATE!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><Int>() }
|
<!UNRESOLVED_REFERENCE!>a<!> <!UNSAFE_CALL!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><Int>() }
|
||||||
d checkType { _<Short>() }
|
d checkType { _<Short>() }
|
||||||
}
|
}
|
||||||
|
|
||||||
foobar { (a, b), (c, d) ->
|
foobar { (a, b), (c, d) ->
|
||||||
<!UNRESOLVED_REFERENCE!>b<!> <!INAPPLICABLE_CANDIDATE!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><String>() }
|
<!UNRESOLVED_REFERENCE!>b<!> <!UNSAFE_CALL!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><String>() }
|
||||||
c checkType { _<Double>() }
|
c checkType { _<Double>() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
+2
-2
@@ -20,7 +20,7 @@ class A : Outer<Double, Short>() {
|
|||||||
|
|
||||||
fun foo() {
|
fun foo() {
|
||||||
Derived().foo() checkType { _<Outer<String, Int>.Inner<Char>>() }
|
Derived().foo() checkType { _<Outer<String, Int>.Inner<Char>>() }
|
||||||
Derived().baz() <!INAPPLICABLE_CANDIDATE!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><Map<Char, String>>() }
|
Derived().baz() <!UNSAFE_CALL!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><Map<Char, String>>() }
|
||||||
A.B().bar() checkType { _<Outer<Float, Long>.Inner<String>>() }
|
A.B().bar() checkType { _<Outer<Float, Long>.Inner<String>>() }
|
||||||
A.B().x() <!INAPPLICABLE_CANDIDATE!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><Map<String, Float>>() }
|
A.B().x() <!UNSAFE_CALL!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><Map<String, Float>>() }
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -43,7 +43,7 @@ fun test() {
|
|||||||
x = foobar<String>()
|
x = foobar<String>()
|
||||||
|
|
||||||
x().foo().a() checkType { <!INAPPLICABLE_CANDIDATE!>_<!><A<String, Double, Short, Long>>() }
|
x().foo().a() checkType { <!INAPPLICABLE_CANDIDATE!>_<!><A<String, Double, Short, Long>>() }
|
||||||
x().bar() <!INAPPLICABLE_CANDIDATE!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><A<String, Double, Short, Char>>() }
|
x().bar() <!UNSAFE_CALL!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><A<String, Double, Short, Char>>() }
|
||||||
|
|
||||||
x = foobar<Int>()
|
x = foobar<Int>()
|
||||||
|
|
||||||
@@ -51,5 +51,5 @@ fun test() {
|
|||||||
y = noParameters()
|
y = noParameters()
|
||||||
|
|
||||||
y().foo().a() checkType { _<A<Any, Double, Short, Long>>() }
|
y().foo().a() checkType { _<A<Any, Double, Short, Long>>() }
|
||||||
y().bar() <!INAPPLICABLE_CANDIDATE!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><A<Any, Double, Short, Char>>() }
|
y().bar() <!UNSAFE_CALL!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><A<Any, Double, Short, Char>>() }
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -44,7 +44,7 @@ class Outer<T> {
|
|||||||
x = foobar<String>()
|
x = foobar<String>()
|
||||||
|
|
||||||
x().foo().a() checkType { <!INAPPLICABLE_CANDIDATE!>_<!><A<T, F, String, Double, Short, Long>>() }
|
x().foo().a() checkType { <!INAPPLICABLE_CANDIDATE!>_<!><A<T, F, String, Double, Short, Long>>() }
|
||||||
x().bar() <!INAPPLICABLE_CANDIDATE!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><A<T, F, String, Double, Short, Char>>() }
|
x().bar() <!UNSAFE_CALL!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><A<T, F, String, Double, Short, Char>>() }
|
||||||
|
|
||||||
x = foobar<Int>()
|
x = foobar<Int>()
|
||||||
x = z.foobar<String>()
|
x = z.foobar<String>()
|
||||||
@@ -53,7 +53,7 @@ class Outer<T> {
|
|||||||
y = noParameters()
|
y = noParameters()
|
||||||
|
|
||||||
y().foo().a() checkType { _<A<T, F, Any, Double, Short, Long>>() }
|
y().foo().a() checkType { _<A<T, F, Any, Double, Short, Long>>() }
|
||||||
y().bar() <!INAPPLICABLE_CANDIDATE!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><A<T, F, Any, Double, Short, Char>>() }
|
y().bar() <!UNSAFE_CALL!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><A<T, F, Any, Double, Short, Char>>() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -15,5 +15,5 @@ class Derived : BaseDerived2<Int>() {
|
|||||||
|
|
||||||
fun foo() {
|
fun foo() {
|
||||||
Derived().foo() checkType { _<Outer<Int, String>.Inner<Char>>() }
|
Derived().foo() checkType { _<Outer<Int, String>.Inner<Char>>() }
|
||||||
Derived().baz() <!INAPPLICABLE_CANDIDATE!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><Map<Char, Int>>() }
|
Derived().baz() <!UNSAFE_CALL!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><Map<Char, Int>>() }
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
+4
-4
@@ -23,7 +23,7 @@ fun testNoSmartCast1(s: String?) {
|
|||||||
if (s != null) ""
|
if (s != null) ""
|
||||||
else noSmartCast1(null) { "" }
|
else noSmartCast1(null) { "" }
|
||||||
)
|
)
|
||||||
s.<!INAPPLICABLE_CANDIDATE!>length<!>
|
s.<!UNSAFE_CALL!>length<!>
|
||||||
}
|
}
|
||||||
|
|
||||||
fun testNoSmartCast2(s: String?) {
|
fun testNoSmartCast2(s: String?) {
|
||||||
@@ -31,7 +31,7 @@ fun testNoSmartCast2(s: String?) {
|
|||||||
if (s != null) ( {""} )
|
if (s != null) ( {""} )
|
||||||
else noSmartCast2(null) { "" }
|
else noSmartCast2(null) { "" }
|
||||||
)
|
)
|
||||||
s.<!INAPPLICABLE_CANDIDATE!>length<!>
|
s.<!UNSAFE_CALL!>length<!>
|
||||||
}
|
}
|
||||||
|
|
||||||
fun testNoSmartCast3(s: String?) {
|
fun testNoSmartCast3(s: String?) {
|
||||||
@@ -39,7 +39,7 @@ fun testNoSmartCast3(s: String?) {
|
|||||||
if (s != null) ""
|
if (s != null) ""
|
||||||
else noSmartCast3(null) { "" }
|
else noSmartCast3(null) { "" }
|
||||||
)
|
)
|
||||||
s.<!INAPPLICABLE_CANDIDATE!>length<!>
|
s.<!UNSAFE_CALL!>length<!>
|
||||||
}
|
}
|
||||||
|
|
||||||
// KT-36069
|
// KT-36069
|
||||||
@@ -48,5 +48,5 @@ fun testNoSmartCast4(s: String?) {
|
|||||||
if (s != null) ( {""} )
|
if (s != null) ( {""} )
|
||||||
else noSmartCast4(null) { "" }
|
else noSmartCast4(null) { "" }
|
||||||
)
|
)
|
||||||
s.<!INAPPLICABLE_CANDIDATE!>length<!>
|
s.<!UNSAFE_CALL!>length<!>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,14 +3,14 @@ package c
|
|||||||
interface A<T>
|
interface A<T>
|
||||||
|
|
||||||
fun test(a: A<Int>?) {
|
fun test(a: A<Int>?) {
|
||||||
a.<!INAPPLICABLE_CANDIDATE!>foo<!>() //no error
|
a.<!UNSAFE_CALL!>foo<!>() //no error
|
||||||
}
|
}
|
||||||
|
|
||||||
fun <R> A<R>.foo() {}
|
fun <R> A<R>.foo() {}
|
||||||
|
|
||||||
//------------
|
//------------
|
||||||
fun test(nullabilityInfoMap: Map<Int, Any>?) {
|
fun test(nullabilityInfoMap: Map<Int, Any>?) {
|
||||||
nullabilityInfoMap.<!INAPPLICABLE_CANDIDATE!>iterator<!>() //no error
|
nullabilityInfoMap.<!UNSAFE_CALL!>iterator<!>() //no error
|
||||||
}
|
}
|
||||||
|
|
||||||
//resolves to
|
//resolves to
|
||||||
@@ -20,7 +20,7 @@ public fun <K,V> Map<K,V>.iterator(): Iterator<Map.Entry<K,V>> {}
|
|||||||
//-------------
|
//-------------
|
||||||
fun foo() : Boolean {
|
fun foo() : Boolean {
|
||||||
val nullableList = getNullableList()
|
val nullableList = getNullableList()
|
||||||
return nullableList.<!INAPPLICABLE_CANDIDATE!>contains<!>("")
|
return nullableList.<!UNSAFE_CALL!>contains<!>("")
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+4
-4
@@ -19,9 +19,9 @@ public abstract class CollectionWithSize implements java.util.Collection<String>
|
|||||||
// FILE: main.kt
|
// FILE: main.kt
|
||||||
|
|
||||||
fun main(c: CollectionWithSize) {
|
fun main(c: CollectionWithSize) {
|
||||||
CompressionType.ZIP.<!AMBIGUITY!>name<!> <!INAPPLICABLE_CANDIDATE!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><Double>() }
|
CompressionType.ZIP.<!AMBIGUITY!>name<!> <!UNSAFE_CALL!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><Double>() }
|
||||||
c.<!AMBIGUITY!>size<!> <!INAPPLICABLE_CANDIDATE!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><String>() }
|
c.<!AMBIGUITY!>size<!> <!UNSAFE_CALL!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><String>() }
|
||||||
|
|
||||||
<!UNRESOLVED_REFERENCE!>CompressionType.ZIP::name<!> <!INAPPLICABLE_CANDIDATE!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><kotlin.reflect.KProperty0<Double>>() }
|
<!UNRESOLVED_REFERENCE!>CompressionType.ZIP::name<!> <!UNSAFE_CALL!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><kotlin.reflect.KProperty0<Double>>() }
|
||||||
<!UNRESOLVED_REFERENCE!>c::size<!> <!INAPPLICABLE_CANDIDATE!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><kotlin.reflect.KProperty0<String>>() }
|
<!UNRESOLVED_REFERENCE!>c::size<!> <!UNSAFE_CALL!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><kotlin.reflect.KProperty0<String>>() }
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-4
@@ -20,9 +20,9 @@ public abstract class CollectionWithSize implements java.util.Collection<String>
|
|||||||
// FILE: main.kt
|
// FILE: main.kt
|
||||||
|
|
||||||
fun main(c: CollectionWithSize) {
|
fun main(c: CollectionWithSize) {
|
||||||
CompressionType.ZIP.<!AMBIGUITY!>name<!> <!INAPPLICABLE_CANDIDATE!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><Double>() }
|
CompressionType.ZIP.<!AMBIGUITY!>name<!> <!UNSAFE_CALL!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><Double>() }
|
||||||
c.<!AMBIGUITY!>size<!> <!INAPPLICABLE_CANDIDATE!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><String>() }
|
c.<!AMBIGUITY!>size<!> <!UNSAFE_CALL!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><String>() }
|
||||||
|
|
||||||
<!UNRESOLVED_REFERENCE!>CompressionType.ZIP::name<!> <!INAPPLICABLE_CANDIDATE!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><kotlin.reflect.KProperty0<Double>>() }
|
<!UNRESOLVED_REFERENCE!>CompressionType.ZIP::name<!> <!UNSAFE_CALL!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><kotlin.reflect.KProperty0<Double>>() }
|
||||||
<!UNRESOLVED_REFERENCE!>c::size<!> <!INAPPLICABLE_CANDIDATE!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><kotlin.reflect.KProperty0<String>>() }
|
<!UNRESOLVED_REFERENCE!>c::size<!> <!UNSAFE_CALL!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><kotlin.reflect.KProperty0<String>>() }
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-4
@@ -19,9 +19,9 @@ public abstract class CollectionWithSize implements java.util.Collection<String>
|
|||||||
// FILE: main.kt
|
// FILE: main.kt
|
||||||
|
|
||||||
fun main(c: CollectionWithSize) {
|
fun main(c: CollectionWithSize) {
|
||||||
CompressionType.ZIP.<!AMBIGUITY!>name<!> <!INAPPLICABLE_CANDIDATE!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><Double>() }
|
CompressionType.ZIP.<!AMBIGUITY!>name<!> <!UNSAFE_CALL!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><Double>() }
|
||||||
c.<!AMBIGUITY!>size<!> <!INAPPLICABLE_CANDIDATE!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><String>() }
|
c.<!AMBIGUITY!>size<!> <!UNSAFE_CALL!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><String>() }
|
||||||
|
|
||||||
<!UNRESOLVED_REFERENCE!>CompressionType.ZIP::name<!> <!INAPPLICABLE_CANDIDATE!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><kotlin.reflect.KProperty0<Double>>() }
|
<!UNRESOLVED_REFERENCE!>CompressionType.ZIP::name<!> <!UNSAFE_CALL!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><kotlin.reflect.KProperty0<Double>>() }
|
||||||
<!UNRESOLVED_REFERENCE!>c::size<!> <!INAPPLICABLE_CANDIDATE!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><kotlin.reflect.KProperty0<String>>() }
|
<!UNRESOLVED_REFERENCE!>c::size<!> <!UNSAFE_CALL!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><kotlin.reflect.KProperty0<String>>() }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,12 +17,12 @@ public interface J2 extends J {
|
|||||||
// FILE: main.kt
|
// FILE: main.kt
|
||||||
fun main() {
|
fun main() {
|
||||||
<!INAPPLICABLE_CANDIDATE!>J<!> { s: String -> s} // should be prohibited, because SAM value parameter has nullable type
|
<!INAPPLICABLE_CANDIDATE!>J<!> { s: String -> s} // should be prohibited, because SAM value parameter has nullable type
|
||||||
J { "" + it.<!INAPPLICABLE_CANDIDATE!>length<!> }
|
J { "" + it.<!UNSAFE_CALL!>length<!> }
|
||||||
J { null }
|
J { null }
|
||||||
J { it?.length?.toString() }
|
J { it?.length?.toString() }
|
||||||
|
|
||||||
<!INAPPLICABLE_CANDIDATE!>J2<!> { s: String -> s}
|
<!INAPPLICABLE_CANDIDATE!>J2<!> { s: String -> s}
|
||||||
J2 { "" + it.<!INAPPLICABLE_CANDIDATE!>length<!> }
|
J2 { "" + it.<!UNSAFE_CALL!>length<!> }
|
||||||
J2 { null }
|
J2 { null }
|
||||||
J2 { it?.length?.toString() }
|
J2 { it?.length?.toString() }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,6 @@ public class A {
|
|||||||
// FILE: main.kt
|
// FILE: main.kt
|
||||||
|
|
||||||
fun foo(a: A) {
|
fun foo(a: A) {
|
||||||
a.<!AMBIGUITY!>foo<!>() <!INAPPLICABLE_CANDIDATE!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><String>() }
|
a.<!AMBIGUITY!>foo<!>() <!UNSAFE_CALL!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><String>() }
|
||||||
A.<!AMBIGUITY!>bar<!>() <!INAPPLICABLE_CANDIDATE!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><String>() }
|
A.<!AMBIGUITY!>bar<!>() <!UNSAFE_CALL!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><String>() }
|
||||||
}
|
}
|
||||||
|
|||||||
+13
-13
@@ -12,21 +12,21 @@ fun test(x : Int?, a : A?) {
|
|||||||
x.<!NONE_APPLICABLE!>plus<!>(1)
|
x.<!NONE_APPLICABLE!>plus<!>(1)
|
||||||
x?.plus(1)
|
x?.plus(1)
|
||||||
x <!NONE_APPLICABLE!>+<!> 1
|
x <!NONE_APPLICABLE!>+<!> 1
|
||||||
<!INAPPLICABLE_CANDIDATE!>-<!>x
|
<!UNSAFE_CALL!>-<!>x
|
||||||
x.<!INAPPLICABLE_CANDIDATE!>unaryMinus<!>()
|
x.<!UNSAFE_CALL!>unaryMinus<!>()
|
||||||
x?.unaryMinus()
|
x?.unaryMinus()
|
||||||
|
|
||||||
a.<!INAPPLICABLE_CANDIDATE!>plus<!>(1)
|
a.<!UNSAFE_CALL!>plus<!>(1)
|
||||||
a?.plus(1)
|
a?.plus(1)
|
||||||
a <!INAPPLICABLE_CANDIDATE!>plus<!> 1
|
a <!UNSAFE_CALL!>plus<!> 1
|
||||||
a <!INAPPLICABLE_CANDIDATE!>+<!> 1
|
a <!UNSAFE_CALL!>+<!> 1
|
||||||
<!INAPPLICABLE_CANDIDATE!>-<!>a
|
<!UNSAFE_CALL!>-<!>a
|
||||||
a.<!INAPPLICABLE_CANDIDATE!>unaryMinus<!>()
|
a.<!UNSAFE_CALL!>unaryMinus<!>()
|
||||||
a?.unaryMinus()
|
a?.unaryMinus()
|
||||||
|
|
||||||
a.<!INAPPLICABLE_CANDIDATE!>div<!>(1)
|
a.<!UNSAFE_CALL!>div<!>(1)
|
||||||
a <!INAPPLICABLE_CANDIDATE!>/<!> 1
|
a <!UNSAFE_CALL!>/<!> 1
|
||||||
a <!INAPPLICABLE_CANDIDATE!>div<!> 1
|
a <!UNSAFE_CALL!>div<!> 1
|
||||||
a?.div(1)
|
a?.div(1)
|
||||||
|
|
||||||
a.times(1)
|
a.times(1)
|
||||||
@@ -34,8 +34,8 @@ fun test(x : Int?, a : A?) {
|
|||||||
a times 1
|
a times 1
|
||||||
a?.times(1)
|
a?.times(1)
|
||||||
|
|
||||||
1 <!INAPPLICABLE_CANDIDATE!>in<!> a
|
1 <!UNSAFE_CALL!>in<!> a
|
||||||
a <!INAPPLICABLE_CANDIDATE!>contains<!> 1
|
a <!UNSAFE_CALL!>contains<!> 1
|
||||||
a.<!INAPPLICABLE_CANDIDATE!>contains<!>(1)
|
a.<!UNSAFE_CALL!>contains<!>(1)
|
||||||
a?.contains(1)
|
a?.contains(1)
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
+3
-3
@@ -7,7 +7,7 @@ fun main() {
|
|||||||
val x: Foo? = null
|
val x: Foo? = null
|
||||||
val y: Foo? = null
|
val y: Foo? = null
|
||||||
|
|
||||||
x.<!INAPPLICABLE_CANDIDATE!>foo<!>(y)
|
x.<!UNSAFE_CALL!>foo<!>(y)
|
||||||
x!!.<!INAPPLICABLE_CANDIDATE!>foo<!>(y)
|
x!!.<!INAPPLICABLE_CANDIDATE!>foo<!>(y)
|
||||||
x.foo(y!!)
|
x.foo(y!!)
|
||||||
x!!.foo(y!!)
|
x!!.foo(y!!)
|
||||||
@@ -16,8 +16,8 @@ fun main() {
|
|||||||
val b: Foo? = null
|
val b: Foo? = null
|
||||||
val c: Foo? = null
|
val c: Foo? = null
|
||||||
|
|
||||||
a.<!INAPPLICABLE_CANDIDATE!>foo<!>(b.<!INAPPLICABLE_CANDIDATE!>foo<!>(c))
|
a.<!UNSAFE_CALL!>foo<!>(b.<!UNSAFE_CALL!>foo<!>(c))
|
||||||
a!!.foo(b.<!INAPPLICABLE_CANDIDATE!>foo<!>(c))
|
a!!.foo(b.<!UNSAFE_CALL!>foo<!>(c))
|
||||||
a.foo(b!!.<!INAPPLICABLE_CANDIDATE!>foo<!>(c))
|
a.foo(b!!.<!INAPPLICABLE_CANDIDATE!>foo<!>(c))
|
||||||
a!!.foo(b!!.<!INAPPLICABLE_CANDIDATE!>foo<!>(c))
|
a!!.foo(b!!.<!INAPPLICABLE_CANDIDATE!>foo<!>(c))
|
||||||
a.foo(b.foo(c!!))
|
a.foo(b.foo(c!!))
|
||||||
|
|||||||
+6
-6
@@ -6,8 +6,8 @@ fun A.bar() {}
|
|||||||
fun A?.buzz() {}
|
fun A?.buzz() {}
|
||||||
|
|
||||||
fun test(a : A?) {
|
fun test(a : A?) {
|
||||||
a.<!INAPPLICABLE_CANDIDATE!>foo<!>() // error
|
a.<!UNSAFE_CALL!>foo<!>() // error
|
||||||
a.<!INAPPLICABLE_CANDIDATE!>bar<!>() // error
|
a.<!UNSAFE_CALL!>bar<!>() // error
|
||||||
a.buzz()
|
a.buzz()
|
||||||
|
|
||||||
a?.foo()
|
a?.foo()
|
||||||
@@ -30,12 +30,12 @@ fun A.test2() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun A?.test3() {
|
fun A?.test3() {
|
||||||
<!INAPPLICABLE_CANDIDATE!>foo<!>() // error
|
<!UNSAFE_CALL!>foo<!>() // error
|
||||||
<!INAPPLICABLE_CANDIDATE!>bar<!>() // error
|
<!UNSAFE_CALL!>bar<!>() // error
|
||||||
buzz()
|
buzz()
|
||||||
|
|
||||||
this.<!INAPPLICABLE_CANDIDATE!>foo<!>() // error
|
this.<!UNSAFE_CALL!>foo<!>() // error
|
||||||
this.<!INAPPLICABLE_CANDIDATE!>bar<!>() // error
|
this.<!UNSAFE_CALL!>bar<!>() // error
|
||||||
this.buzz()
|
this.buzz()
|
||||||
|
|
||||||
this?.foo()
|
this?.foo()
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ package kt1270
|
|||||||
|
|
||||||
fun foo() {
|
fun foo() {
|
||||||
val sc = java.util.HashMap<String, SomeClass>()[""]
|
val sc = java.util.HashMap<String, SomeClass>()[""]
|
||||||
val value = sc.<!INAPPLICABLE_CANDIDATE!>value<!>
|
val value = sc.<!UNSAFE_CALL!>value<!>
|
||||||
}
|
}
|
||||||
|
|
||||||
private class SomeClass() {
|
private class SomeClass() {
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ package e
|
|||||||
fun main() {
|
fun main() {
|
||||||
val compareTo = 1
|
val compareTo = 1
|
||||||
val s: String? = null
|
val s: String? = null
|
||||||
s.<!INAPPLICABLE_CANDIDATE!>compareTo<!>("")
|
s.<!UNSAFE_CALL!>compareTo<!>("")
|
||||||
|
|
||||||
val bar = 2
|
val bar = 2
|
||||||
s.<!UNRESOLVED_REFERENCE!>bar<!>()
|
s.<!UNRESOLVED_REFERENCE!>bar<!>()
|
||||||
|
|||||||
+1
-1
@@ -13,5 +13,5 @@ public class B {
|
|||||||
|
|
||||||
// FILE: main.kt
|
// FILE: main.kt
|
||||||
fun test() {
|
fun test() {
|
||||||
B.bar() { it.<!INAPPLICABLE_CANDIDATE!>hashCode<!>() > 0 }
|
B.bar() { it.<!UNSAFE_CALL!>hashCode<!>() > 0 }
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -22,11 +22,11 @@ fun test() {
|
|||||||
var platformJ = J.staticJ
|
var platformJ = J.staticJ
|
||||||
|
|
||||||
+platformNN
|
+platformNN
|
||||||
<!INAPPLICABLE_CANDIDATE!>+<!>platformN
|
<!UNSAFE_CALL!>+<!>platformN
|
||||||
+platformJ
|
+platformJ
|
||||||
|
|
||||||
++platformNN
|
++platformNN
|
||||||
<!INAPPLICABLE_CANDIDATE!>++<!>platformN
|
<!UNSAFE_CALL!>++<!>platformN
|
||||||
++platformJ
|
++platformJ
|
||||||
|
|
||||||
platformNN++
|
platformNN++
|
||||||
|
|||||||
+2
-2
@@ -21,11 +21,11 @@ fun test() {
|
|||||||
val platformJ = J.staticJ
|
val platformJ = J.staticJ
|
||||||
|
|
||||||
platformNN[0]
|
platformNN[0]
|
||||||
<!INAPPLICABLE_CANDIDATE!>platformN[0]<!>
|
<!UNSAFE_CALL!>platformN[0]<!>
|
||||||
platformJ[0]
|
platformJ[0]
|
||||||
|
|
||||||
platformNN[0] = 1
|
platformNN[0] = 1
|
||||||
<!INAPPLICABLE_CANDIDATE!>platformN[0] = 1<!>
|
<!UNSAFE_CALL!>platformN[0] = 1<!>
|
||||||
platformJ[0] = 1
|
platformJ[0] = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -43,6 +43,6 @@ fun test() {
|
|||||||
platformJ || false
|
platformJ || false
|
||||||
|
|
||||||
!platformNN
|
!platformNN
|
||||||
<!INAPPLICABLE_CANDIDATE!>!<!>platformN
|
<!UNSAFE_CALL!>!<!>platformN
|
||||||
!platformJ
|
!platformJ
|
||||||
}
|
}
|
||||||
Vendored
+1
-1
@@ -19,5 +19,5 @@ public class J {
|
|||||||
// FILE: k.kt
|
// FILE: k.kt
|
||||||
|
|
||||||
var A by J.staticNN
|
var A by J.staticNN
|
||||||
var B by <!INAPPLICABLE_CANDIDATE!>J.staticN<!>
|
var B by <!UNSAFE_CALL!>J.staticN<!>
|
||||||
var C by J.staticJ
|
var C by J.staticJ
|
||||||
Vendored
+2
-2
@@ -23,14 +23,14 @@ fun test() {
|
|||||||
val platformJ = J.staticJ
|
val platformJ = J.staticJ
|
||||||
|
|
||||||
platformNN.foo()
|
platformNN.foo()
|
||||||
platformN.<!INAPPLICABLE_CANDIDATE!>foo<!>()
|
platformN.<!UNSAFE_CALL!>foo<!>()
|
||||||
platformJ.foo()
|
platformJ.foo()
|
||||||
|
|
||||||
with(platformNN) {
|
with(platformNN) {
|
||||||
foo()
|
foo()
|
||||||
}
|
}
|
||||||
with(platformN) {
|
with(platformN) {
|
||||||
<!INAPPLICABLE_CANDIDATE!>foo<!>()
|
<!UNSAFE_CALL!>foo<!>()
|
||||||
}
|
}
|
||||||
with(platformJ) {
|
with(platformJ) {
|
||||||
foo()
|
foo()
|
||||||
|
|||||||
Vendored
+2
-2
@@ -25,14 +25,14 @@ fun test() {
|
|||||||
val platformJ = J.staticJ
|
val platformJ = J.staticJ
|
||||||
|
|
||||||
platformNN.foo()
|
platformNN.foo()
|
||||||
platformN.<!INAPPLICABLE_CANDIDATE!>foo<!>()
|
platformN.<!UNSAFE_CALL!>foo<!>()
|
||||||
platformJ.foo()
|
platformJ.foo()
|
||||||
|
|
||||||
with(platformNN) {
|
with(platformNN) {
|
||||||
foo()
|
foo()
|
||||||
}
|
}
|
||||||
with(platformN) {
|
with(platformN) {
|
||||||
<!INAPPLICABLE_CANDIDATE!>foo<!>()
|
<!UNSAFE_CALL!>foo<!>()
|
||||||
}
|
}
|
||||||
with(platformJ) {
|
with(platformJ) {
|
||||||
foo()
|
foo()
|
||||||
|
|||||||
+1
-1
@@ -22,7 +22,7 @@ fun test() {
|
|||||||
val platformJ = J.staticJ
|
val platformJ = J.staticJ
|
||||||
|
|
||||||
for (x in platformNN) {}
|
for (x in platformNN) {}
|
||||||
<!INAPPLICABLE_CANDIDATE!>for (x in platformN) {}<!>
|
<!UNSAFE_CALL!>for (x in platformN) {}<!>
|
||||||
for (x in platformJ) {}
|
for (x in platformJ) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -18,6 +18,6 @@ public class J {
|
|||||||
|
|
||||||
fun test() {
|
fun test() {
|
||||||
J.staticNN()
|
J.staticNN()
|
||||||
J.<!INAPPLICABLE_CANDIDATE!>staticN<!>()
|
J.<!UNSAFE_CALL!>staticN<!>()
|
||||||
J.staticJ()
|
J.staticJ()
|
||||||
}
|
}
|
||||||
+1
-1
@@ -16,7 +16,7 @@ public class J {
|
|||||||
|
|
||||||
fun foo(collection: Collection<J>) {
|
fun foo(collection: Collection<J>) {
|
||||||
val mapped = collection.map { it.method() }
|
val mapped = collection.map { it.method() }
|
||||||
mapped[0].<!INAPPLICABLE_CANDIDATE!>length<!>
|
mapped[0].<!UNSAFE_CALL!>length<!>
|
||||||
}
|
}
|
||||||
|
|
||||||
public fun <T, R> Iterable<T>.map(transform: (T) -> R): List<R> {
|
public fun <T, R> Iterable<T>.map(transform: (T) -> R): List<R> {
|
||||||
|
|||||||
Vendored
-32
@@ -1,32 +0,0 @@
|
|||||||
// !DIAGNOSTICS: -UNUSED_VARIABLE
|
|
||||||
// FILE: J.java
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.*;
|
|
||||||
|
|
||||||
public class J {
|
|
||||||
public interface Multi {
|
|
||||||
String component1();
|
|
||||||
String component2();
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
public static Multi staticNN;
|
|
||||||
@Nullable
|
|
||||||
public static Multi staticN;
|
|
||||||
public static Multi 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
|
|
||||||
|
|
||||||
val (a1, b1) = platformNN
|
|
||||||
val (<!INAPPLICABLE_CANDIDATE!>a2<!>, <!INAPPLICABLE_CANDIDATE!>b2<!>) = platformN
|
|
||||||
val (a3, b3) = platformJ
|
|
||||||
}
|
|
||||||
+1
@@ -1,3 +1,4 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
// !DIAGNOSTICS: -UNUSED_VARIABLE
|
// !DIAGNOSTICS: -UNUSED_VARIABLE
|
||||||
// FILE: J.java
|
// FILE: J.java
|
||||||
|
|
||||||
|
|||||||
Vendored
+2
-2
@@ -21,11 +21,11 @@ fun test() {
|
|||||||
val platformJ = J.staticJ
|
val platformJ = J.staticJ
|
||||||
|
|
||||||
platformNN[0]
|
platformNN[0]
|
||||||
<!INAPPLICABLE_CANDIDATE!>platformN[0]<!>
|
<!UNSAFE_CALL!>platformN[0]<!>
|
||||||
platformJ[0]
|
platformJ[0]
|
||||||
|
|
||||||
platformNN[0] = 1
|
platformNN[0] = 1
|
||||||
<!INAPPLICABLE_CANDIDATE!>platformN[0] = 1<!>
|
<!UNSAFE_CALL!>platformN[0] = 1<!>
|
||||||
platformJ[0] = 1
|
platformJ[0] = 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Vendored
+2
-2
@@ -8,8 +8,8 @@ class E : B1() {
|
|||||||
fun baz() {
|
fun baz() {
|
||||||
val x: String? = ""
|
val x: String? = ""
|
||||||
|
|
||||||
x.<!INAPPLICABLE_CANDIDATE!>foo<!>(x)
|
x.<!UNSAFE_CALL!>foo<!>(x)
|
||||||
x.<!INAPPLICABLE_CANDIDATE!>foo<!>("")
|
x.<!UNSAFE_CALL!>foo<!>("")
|
||||||
x.<!INAPPLICABLE_CANDIDATE!>bar<!>(x)
|
x.<!INAPPLICABLE_CANDIDATE!>bar<!>(x)
|
||||||
x.bar("")
|
x.bar("")
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -19,5 +19,5 @@ class C(p: Any, val v: Any) {
|
|||||||
|
|
||||||
var test5
|
var test5
|
||||||
get() { return <!UNRESOLVED_REFERENCE!>p<!> }
|
get() { return <!UNRESOLVED_REFERENCE!>p<!> }
|
||||||
set(nv) { <!UNRESOLVED_REFERENCE!>p<!>.<!INAPPLICABLE_CANDIDATE!>let<!> {} }
|
set(nv) { <!UNRESOLVED_REFERENCE!>p<!>.<!UNSAFE_CALL!>let<!> {} }
|
||||||
}
|
}
|
||||||
@@ -10,7 +10,7 @@ class C(override val t: Any?) : B<Any?, Any>
|
|||||||
fun f(b: B<*, Any>) {
|
fun f(b: B<*, Any>) {
|
||||||
val y = b.t
|
val y = b.t
|
||||||
if (y is String?) {
|
if (y is String?) {
|
||||||
y.<!INAPPLICABLE_CANDIDATE!>length<!>
|
y.<!UNSAFE_CALL!>length<!>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,6 @@ fun f(): Unit {
|
|||||||
val i : Int? = null
|
val i : Int? = null
|
||||||
i <!NONE_APPLICABLE!>+<!> 1
|
i <!NONE_APPLICABLE!>+<!> 1
|
||||||
set + 1
|
set + 1
|
||||||
1 <!INAPPLICABLE_CANDIDATE!>in<!> set
|
1 <!UNSAFE_CALL!>in<!> set
|
||||||
1 in 2
|
1 in 2
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,5 +8,5 @@ fun Array<String>.length() : Int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun test(array : Array<String?>?) {
|
fun test(array : Array<String?>?) {
|
||||||
array?.sure<Array<String?>>().<!INAPPLICABLE_CANDIDATE!>length<!>()
|
array?.sure<Array<String?>>().<!UNSAFE_CALL!>length<!>()
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -4,7 +4,7 @@
|
|||||||
operator fun String.invoke(i: Int) {}
|
operator fun String.invoke(i: Int) {}
|
||||||
|
|
||||||
fun foo(s: String?) {
|
fun foo(s: String?) {
|
||||||
<!INAPPLICABLE_CANDIDATE!>s<!>(1)
|
<!UNSAFE_CALL!>s<!>(1)
|
||||||
|
|
||||||
<!INAPPLICABLE_CANDIDATE!>(s ?: null)(1)<!>
|
<!UNSAFE_CALL!>(s ?: null)(1)<!>
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-6
@@ -12,7 +12,7 @@ class Another1 {
|
|||||||
|
|
||||||
fun Another1.main(x: Bar1<String>?) {
|
fun Another1.main(x: Bar1<String>?) {
|
||||||
x?.value {}
|
x?.value {}
|
||||||
x?.value.<!INAPPLICABLE_CANDIDATE!>invoke<!>({})
|
x?.value.<!UNSAFE_CALL!>invoke<!>({})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test case 2: additional receiver, non-generic invoke
|
// Test case 2: additional receiver, non-generic invoke
|
||||||
@@ -26,7 +26,7 @@ class Another2 {
|
|||||||
|
|
||||||
fun Another2.main(x: Bar2<String>?) {
|
fun Another2.main(x: Bar2<String>?) {
|
||||||
x?.value(1)
|
x?.value(1)
|
||||||
x?.value.<!INAPPLICABLE_CANDIDATE!>invoke<!>(1)
|
x?.value.<!UNSAFE_CALL!>invoke<!>(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test case 3: additional generic receiver, generic invoke
|
// Test case 3: additional generic receiver, generic invoke
|
||||||
@@ -40,7 +40,7 @@ class Another3<T> {
|
|||||||
|
|
||||||
fun <K> Another3<K>.main(x: Bar3<K>?) {
|
fun <K> Another3<K>.main(x: Bar3<K>?) {
|
||||||
x?.value(1)
|
x?.value(1)
|
||||||
x?.value.<!INAPPLICABLE_CANDIDATE!>invoke<!>(1)
|
x?.value.<!UNSAFE_CALL!>invoke<!>(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test case 4: additional receiver, generic invoke with nullable receiver
|
// Test case 4: additional receiver, generic invoke with nullable receiver
|
||||||
@@ -68,7 +68,7 @@ class Another5 {
|
|||||||
|
|
||||||
fun Another5.main(x: Bar5?) {
|
fun Another5.main(x: Bar5?) {
|
||||||
x?.value {}
|
x?.value {}
|
||||||
x?.value.<!INAPPLICABLE_CANDIDATE!>invoke<!>({})
|
x?.value.<!UNSAFE_CALL!>invoke<!>({})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test case 6: top-level generic invoke
|
// Test case 6: top-level generic invoke
|
||||||
@@ -96,7 +96,7 @@ operator fun <T> Foo7<T>.invoke(x: Int) {}
|
|||||||
|
|
||||||
fun Another7.main(x: Bar7<String>?) {
|
fun Another7.main(x: Bar7<String>?) {
|
||||||
x?.value(1)
|
x?.value(1)
|
||||||
x?.value.<!INAPPLICABLE_CANDIDATE!>invoke<!>(1)
|
x?.value.<!UNSAFE_CALL!>invoke<!>(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test case 8: top-level non-generic invoke
|
// Test case 8: top-level non-generic invoke
|
||||||
@@ -136,5 +136,5 @@ class Another10 {
|
|||||||
|
|
||||||
fun Another10.main(x: Bar10<String>?) {
|
fun Another10.main(x: Bar10<String>?) {
|
||||||
x?.value {}
|
x?.value {}
|
||||||
x?.value.<!INAPPLICABLE_CANDIDATE!>invoke<!>({})
|
x?.value.<!UNSAFE_CALL!>invoke<!>({})
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -7,8 +7,8 @@ fun test(a: A) {
|
|||||||
(a.x)("")
|
(a.x)("")
|
||||||
}
|
}
|
||||||
"".<!UNRESOLVED_REFERENCE!>(a.x)()<!>
|
"".<!UNRESOLVED_REFERENCE!>(a.x)()<!>
|
||||||
a.<!INAPPLICABLE_CANDIDATE!>x<!>("")
|
a.<!UNSAFE_CALL!>x<!>("")
|
||||||
<!INAPPLICABLE_CANDIDATE!>(a.x)("")<!>
|
<!UNSAFE_CALL!>(a.x)("")<!>
|
||||||
|
|
||||||
with("") {
|
with("") {
|
||||||
a.<!INAPPLICABLE_CANDIDATE!>x<!>()
|
a.<!INAPPLICABLE_CANDIDATE!>x<!>()
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ class MemberInvokeOwner {
|
|||||||
|
|
||||||
class Cls {
|
class Cls {
|
||||||
fun testImplicitReceiver() {
|
fun testImplicitReceiver() {
|
||||||
<!INAPPLICABLE_CANDIDATE!>nullableExtensionProperty<!>()
|
<!UNSAFE_CALL!>nullableExtensionProperty<!>()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -30,7 +30,7 @@ fun testNullableReceiver(nullable: Cls?) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun testNotNullableReceiver(notNullable: Cls) {
|
fun testNotNullableReceiver(notNullable: Cls) {
|
||||||
notNullable.<!INAPPLICABLE_CANDIDATE!>nullableExtensionProperty<!>()
|
notNullable.<!UNSAFE_CALL!>nullableExtensionProperty<!>()
|
||||||
notNullable?.extensionProperty()
|
notNullable?.extensionProperty()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -38,6 +38,6 @@ fun testFlexibleReceiver() {
|
|||||||
val flexible = JavaClass.createFlexible()
|
val flexible = JavaClass.createFlexible()
|
||||||
flexible.extensionProperty()
|
flexible.extensionProperty()
|
||||||
flexible?.extensionProperty()
|
flexible?.extensionProperty()
|
||||||
flexible.<!INAPPLICABLE_CANDIDATE!>nullableExtensionProperty<!>()
|
flexible.<!UNSAFE_CALL!>nullableExtensionProperty<!>()
|
||||||
flexible?.<!INAPPLICABLE_CANDIDATE!>nullableExtensionProperty<!>()
|
flexible?.<!UNSAFE_CALL!>nullableExtensionProperty<!>()
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -1,7 +1,7 @@
|
|||||||
// !WITH_NEW_INFERENCE
|
// !WITH_NEW_INFERENCE
|
||||||
|
|
||||||
fun f(s: String, action: (String.() -> Unit)?) {
|
fun f(s: String, action: (String.() -> Unit)?) {
|
||||||
s.foo().bar().<!INAPPLICABLE_CANDIDATE!>action<!>()
|
s.foo().bar().<!UNSAFE_CALL!>action<!>()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun String.foo() = ""
|
fun String.foo() = ""
|
||||||
@@ -12,4 +12,4 @@ fun String.bar() = ""
|
|||||||
|
|
||||||
val functions: Map<String, () -> Any> = TODO()
|
val functions: Map<String, () -> Any> = TODO()
|
||||||
|
|
||||||
fun run(name: String) = <!INAPPLICABLE_CANDIDATE!>functions[name]()<!>
|
fun run(name: String) = <!UNSAFE_CALL!>functions[name]()<!>
|
||||||
@@ -22,9 +22,9 @@ public interface J {
|
|||||||
|
|
||||||
// FILE: 1.kt
|
// FILE: 1.kt
|
||||||
fun test(j: J) {
|
fun test(j: J) {
|
||||||
j.<!AMBIGUITY!>foo<!>({ <!UNRESOLVED_REFERENCE!>it<!> <!INAPPLICABLE_CANDIDATE!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><Any>() }; "" }, "") <!INAPPLICABLE_CANDIDATE!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><Int>() }
|
j.<!AMBIGUITY!>foo<!>({ <!UNRESOLVED_REFERENCE!>it<!> <!UNSAFE_CALL!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><Any>() }; "" }, "") <!UNSAFE_CALL!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><Int>() }
|
||||||
|
|
||||||
j.<!AMBIGUITY!>bas<!>({ <!UNRESOLVED_REFERENCE!>it<!> <!INAPPLICABLE_CANDIDATE!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><Any>() }; "" }, "") <!INAPPLICABLE_CANDIDATE!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><Int>() }
|
j.<!AMBIGUITY!>bas<!>({ <!UNRESOLVED_REFERENCE!>it<!> <!UNSAFE_CALL!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><Any>() }; "" }, "") <!UNSAFE_CALL!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><Int>() }
|
||||||
|
|
||||||
// NI: TODO
|
// NI: TODO
|
||||||
j.bar { it checkType { <!INAPPLICABLE_CANDIDATE!>_<!><Any>() }; "" } checkType { _<Int>() }
|
j.bar { it checkType { <!INAPPLICABLE_CANDIDATE!>_<!><Any>() }; "" } checkType { _<Int>() }
|
||||||
|
|||||||
+2
-2
@@ -21,9 +21,9 @@ interface K {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun test(k: K) {
|
fun test(k: K) {
|
||||||
k.<!AMBIGUITY!>foo<!> { <!UNRESOLVED_REFERENCE!>it<!> <!INAPPLICABLE_CANDIDATE!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><Any>() }; "" } <!INAPPLICABLE_CANDIDATE!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><Int>() }
|
k.<!AMBIGUITY!>foo<!> { <!UNRESOLVED_REFERENCE!>it<!> <!UNSAFE_CALL!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><Any>() }; "" } <!UNSAFE_CALL!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><Int>() }
|
||||||
|
|
||||||
k.<!AMBIGUITY!>bas<!> { <!UNRESOLVED_REFERENCE!>it<!> <!INAPPLICABLE_CANDIDATE!>checkType<!> { _<Any?>() }; "" } <!INAPPLICABLE_CANDIDATE!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><Int>() }
|
k.<!AMBIGUITY!>bas<!> { <!UNRESOLVED_REFERENCE!>it<!> <!UNSAFE_CALL!>checkType<!> { _<Any?>() }; "" } <!UNSAFE_CALL!>checkType<!> { <!INAPPLICABLE_CANDIDATE!>_<!><Int>() }
|
||||||
|
|
||||||
// NI: TODO
|
// NI: TODO
|
||||||
k.bar { it checkType { <!INAPPLICABLE_CANDIDATE!>_<!><Any>() }; "" } checkType { _<Int>() }
|
k.bar { it checkType { <!INAPPLICABLE_CANDIDATE!>_<!><Any>() }; "" } checkType { _<Int>() }
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ fun foo(): String {
|
|||||||
var s: String?
|
var s: String?
|
||||||
s = null
|
s = null
|
||||||
s?.length
|
s?.length
|
||||||
s.<!INAPPLICABLE_CANDIDATE!>length<!>
|
s.<!UNSAFE_CALL!>length<!>
|
||||||
if (s == null) return s!!
|
if (s == null) return s!!
|
||||||
var t: String? = "y"
|
var t: String? = "y"
|
||||||
if (t == null) t = "x"
|
if (t == null) t = "x"
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ fun g(a: SomeClass?) {
|
|||||||
// 'a' can be cast to SomeSubClass
|
// 'a' can be cast to SomeSubClass
|
||||||
a.hashCode()
|
a.hashCode()
|
||||||
a.foo
|
a.foo
|
||||||
(a as? SomeSubClass).<!INAPPLICABLE_CANDIDATE!>foo<!>
|
(a as? SomeSubClass).<!UNSAFE_CALL!>foo<!>
|
||||||
(a as SomeSubClass).foo
|
(a as SomeSubClass).foo
|
||||||
}
|
}
|
||||||
val b = (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' can be cast to SomeSubClass
|
||||||
a.hashCode()
|
a.hashCode()
|
||||||
a.foo
|
a.foo
|
||||||
(a as? SomeSubClass).<!INAPPLICABLE_CANDIDATE!>foo<!>
|
(a as? SomeSubClass).<!UNSAFE_CALL!>foo<!>
|
||||||
(a as SomeSubClass).foo
|
(a as SomeSubClass).foo
|
||||||
}
|
}
|
||||||
val c = a as? SomeSubClass
|
val c = a as? SomeSubClass
|
||||||
@@ -29,7 +29,7 @@ fun g(a: SomeClass?) {
|
|||||||
// 'a' and 'c' can be cast to SomeSubClass
|
// 'a' and 'c' can be cast to SomeSubClass
|
||||||
a.hashCode()
|
a.hashCode()
|
||||||
a.foo
|
a.foo
|
||||||
(a as? SomeSubClass).<!INAPPLICABLE_CANDIDATE!>foo<!>
|
(a as? SomeSubClass).<!UNSAFE_CALL!>foo<!>
|
||||||
c.hashCode()
|
c.hashCode()
|
||||||
c.foo
|
c.foo
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ fun g(a: SomeClass?) {
|
|||||||
// 'a' can be cast to SomeSubClass
|
// 'a' can be cast to SomeSubClass
|
||||||
a.hashCode()
|
a.hashCode()
|
||||||
a.foo
|
a.foo
|
||||||
(a as? SomeSubClass).<!INAPPLICABLE_CANDIDATE!>foo<!>
|
(a as? SomeSubClass).<!UNSAFE_CALL!>foo<!>
|
||||||
(a as SomeSubClass).foo
|
(a as SomeSubClass).foo
|
||||||
}
|
}
|
||||||
val b = (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' can be cast to SomeSubClass
|
||||||
a.hashCode()
|
a.hashCode()
|
||||||
a.foo
|
a.foo
|
||||||
(a as? SomeSubClass).<!INAPPLICABLE_CANDIDATE!>foo<!>
|
(a as? SomeSubClass).<!UNSAFE_CALL!>foo<!>
|
||||||
(a as SomeSubClass).foo
|
(a as SomeSubClass).foo
|
||||||
}
|
}
|
||||||
val c = a as? SomeSubClass
|
val c = a as? SomeSubClass
|
||||||
@@ -29,7 +29,7 @@ fun g(a: SomeClass?) {
|
|||||||
// 'a' and 'c' can be cast to SomeSubClass
|
// 'a' and 'c' can be cast to SomeSubClass
|
||||||
a.hashCode()
|
a.hashCode()
|
||||||
a.foo
|
a.foo
|
||||||
(a as? SomeSubClass).<!INAPPLICABLE_CANDIDATE!>foo<!>
|
(a as? SomeSubClass).<!UNSAFE_CALL!>foo<!>
|
||||||
c.hashCode()
|
c.hashCode()
|
||||||
c.foo
|
c.foo
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,18 +18,18 @@ fun g(a: SomeClass?) {
|
|||||||
b = "Hello"
|
b = "Hello"
|
||||||
if (b != null) {
|
if (b != null) {
|
||||||
// 'a' cannot be cast to SomeSubClass!
|
// 'a' cannot be cast to SomeSubClass!
|
||||||
a.<!INAPPLICABLE_CANDIDATE!>hashCode<!>()
|
a.<!UNSAFE_CALL!>hashCode<!>()
|
||||||
a.<!UNRESOLVED_REFERENCE!>foo<!>
|
a.<!UNRESOLVED_REFERENCE!>foo<!>
|
||||||
(a as? SomeSubClass).<!INAPPLICABLE_CANDIDATE!>foo<!>
|
(a as? SomeSubClass).<!UNSAFE_CALL!>foo<!>
|
||||||
(a as SomeSubClass).foo
|
(a as SomeSubClass).foo
|
||||||
}
|
}
|
||||||
var c = a as? SomeSubClass
|
var c = a as? SomeSubClass
|
||||||
c = Impl
|
c = Impl
|
||||||
if (c != null) {
|
if (c != null) {
|
||||||
// 'a' cannot be cast to SomeSubClass
|
// 'a' cannot be cast to SomeSubClass
|
||||||
a.<!INAPPLICABLE_CANDIDATE!>hashCode<!>()
|
a.<!UNSAFE_CALL!>hashCode<!>()
|
||||||
a.<!UNRESOLVED_REFERENCE!>foo<!>
|
a.<!UNRESOLVED_REFERENCE!>foo<!>
|
||||||
(a as? SomeSubClass).<!INAPPLICABLE_CANDIDATE!>foo<!>
|
(a as? SomeSubClass).<!UNSAFE_CALL!>foo<!>
|
||||||
c.hashCode()
|
c.hashCode()
|
||||||
c.foo
|
c.foo
|
||||||
}
|
}
|
||||||
@@ -41,18 +41,18 @@ fun f(a: SomeClass?) {
|
|||||||
if (aa as? SomeSubClass != null) {
|
if (aa as? SomeSubClass != null) {
|
||||||
aa = null
|
aa = null
|
||||||
// 'aa' cannot be cast to SomeSubClass
|
// 'aa' cannot be cast to SomeSubClass
|
||||||
aa.<!INAPPLICABLE_CANDIDATE!>hashCode<!>()
|
aa.<!UNSAFE_CALL!>hashCode<!>()
|
||||||
aa.<!UNRESOLVED_REFERENCE!>foo<!>
|
aa.<!UNRESOLVED_REFERENCE!>foo<!>
|
||||||
(aa as? SomeSubClass).<!INAPPLICABLE_CANDIDATE!>foo<!>
|
(aa as? SomeSubClass).<!UNSAFE_CALL!>foo<!>
|
||||||
(aa as SomeSubClass).foo
|
(aa as SomeSubClass).foo
|
||||||
}
|
}
|
||||||
val b = (aa as? SomeSubClass)?.foo
|
val b = (aa as? SomeSubClass)?.foo
|
||||||
aa = null
|
aa = null
|
||||||
if (b != null) {
|
if (b != null) {
|
||||||
// 'aa' cannot be cast to SomeSubClass
|
// 'aa' cannot be cast to SomeSubClass
|
||||||
aa.<!INAPPLICABLE_CANDIDATE!>hashCode<!>()
|
aa.<!UNSAFE_CALL!>hashCode<!>()
|
||||||
aa.<!UNRESOLVED_REFERENCE!>foo<!>
|
aa.<!UNRESOLVED_REFERENCE!>foo<!>
|
||||||
(aa as? SomeSubClass).<!INAPPLICABLE_CANDIDATE!>foo<!>
|
(aa as? SomeSubClass).<!UNSAFE_CALL!>foo<!>
|
||||||
(aa as SomeSubClass).foo
|
(aa as SomeSubClass).foo
|
||||||
}
|
}
|
||||||
aa = a
|
aa = a
|
||||||
@@ -61,7 +61,7 @@ fun f(a: SomeClass?) {
|
|||||||
// 'c' can be cast to SomeSubClass
|
// 'c' can be cast to SomeSubClass
|
||||||
aa.hashCode()
|
aa.hashCode()
|
||||||
aa.foo
|
aa.foo
|
||||||
(aa as? SomeSubClass).<!INAPPLICABLE_CANDIDATE!>foo<!>
|
(aa as? SomeSubClass).<!UNSAFE_CALL!>foo<!>
|
||||||
c.hashCode()
|
c.hashCode()
|
||||||
c.foo
|
c.foo
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,30 +6,30 @@ fun foo(x : String?, y : String?) {
|
|||||||
y.length
|
y.length
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
x.<!INAPPLICABLE_CANDIDATE!>length<!>
|
x.<!UNSAFE_CALL!>length<!>
|
||||||
y.<!INAPPLICABLE_CANDIDATE!>length<!>
|
y.<!UNSAFE_CALL!>length<!>
|
||||||
}
|
}
|
||||||
if (y != null || x == y) {
|
if (y != null || x == y) {
|
||||||
x.<!INAPPLICABLE_CANDIDATE!>length<!>
|
x.<!UNSAFE_CALL!>length<!>
|
||||||
y.<!INAPPLICABLE_CANDIDATE!>length<!>
|
y.<!UNSAFE_CALL!>length<!>
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// y == null but x != y
|
// y == null but x != y
|
||||||
x.<!INAPPLICABLE_CANDIDATE!>length<!>
|
x.<!UNSAFE_CALL!>length<!>
|
||||||
y.<!INAPPLICABLE_CANDIDATE!>length<!>
|
y.<!UNSAFE_CALL!>length<!>
|
||||||
}
|
}
|
||||||
if (y == null && x != y) {
|
if (y == null && x != y) {
|
||||||
// y == null but x != y
|
// y == null but x != y
|
||||||
x.<!INAPPLICABLE_CANDIDATE!>length<!>
|
x.<!UNSAFE_CALL!>length<!>
|
||||||
y.<!INAPPLICABLE_CANDIDATE!>length<!>
|
y.<!UNSAFE_CALL!>length<!>
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
x.<!INAPPLICABLE_CANDIDATE!>length<!>
|
x.<!UNSAFE_CALL!>length<!>
|
||||||
y.<!INAPPLICABLE_CANDIDATE!>length<!>
|
y.<!UNSAFE_CALL!>length<!>
|
||||||
}
|
}
|
||||||
if (y == null || x != y) {
|
if (y == null || x != y) {
|
||||||
x.<!INAPPLICABLE_CANDIDATE!>length<!>
|
x.<!UNSAFE_CALL!>length<!>
|
||||||
y.<!INAPPLICABLE_CANDIDATE!>length<!>
|
y.<!UNSAFE_CALL!>length<!>
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Both not null
|
// Both not null
|
||||||
|
|||||||
@@ -3,21 +3,21 @@ fun foo(x: String?, y: String?, z: String?, w: String?) {
|
|||||||
if (x != null && y != null && (x == z || y == z))
|
if (x != null && y != null && (x == z || y == z))
|
||||||
z.length
|
z.length
|
||||||
else
|
else
|
||||||
z.<!INAPPLICABLE_CANDIDATE!>length<!>
|
z.<!UNSAFE_CALL!>length<!>
|
||||||
if (x != null || y != null || (x != z && y != z))
|
if (x != null || y != null || (x != z && y != z))
|
||||||
z.<!INAPPLICABLE_CANDIDATE!>length<!>
|
z.<!UNSAFE_CALL!>length<!>
|
||||||
else
|
else
|
||||||
z.<!INAPPLICABLE_CANDIDATE!>length<!>
|
z.<!UNSAFE_CALL!>length<!>
|
||||||
if (x == null || y == null || (x != z && y != z))
|
if (x == null || y == null || (x != z && y != z))
|
||||||
z.<!INAPPLICABLE_CANDIDATE!>length<!>
|
z.<!UNSAFE_CALL!>length<!>
|
||||||
else
|
else
|
||||||
z.length
|
z.length
|
||||||
if (x != null && y == x && z == y && w == z)
|
if (x != null && y == x && z == y && w == z)
|
||||||
w.length
|
w.length
|
||||||
else
|
else
|
||||||
w.<!INAPPLICABLE_CANDIDATE!>length<!>
|
w.<!UNSAFE_CALL!>length<!>
|
||||||
if ((x != null && y == x) || (z != null && y == z))
|
if ((x != null && y == x) || (z != null && y == z))
|
||||||
y.length
|
y.length
|
||||||
else
|
else
|
||||||
y.<!INAPPLICABLE_CANDIDATE!>length<!>
|
y.<!UNSAFE_CALL!>length<!>
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-10
@@ -1,26 +1,26 @@
|
|||||||
fun foo(x: String?, y: String?, z: String?) {
|
fun foo(x: String?, y: String?, z: String?) {
|
||||||
if ((x!!.hashCode() == 0 || y!!.hashCode() == 1) && z!!.hashCode() == 2) {
|
if ((x!!.hashCode() == 0 || y!!.hashCode() == 1) && z!!.hashCode() == 2) {
|
||||||
x.length
|
x.length
|
||||||
y.<!INAPPLICABLE_CANDIDATE!>length<!>
|
y.<!UNSAFE_CALL!>length<!>
|
||||||
// condition is true => z!! after and is called
|
// condition is true => z!! after and is called
|
||||||
z.length
|
z.length
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
x.length
|
x.length
|
||||||
y.<!INAPPLICABLE_CANDIDATE!>length<!>
|
y.<!UNSAFE_CALL!>length<!>
|
||||||
z.<!INAPPLICABLE_CANDIDATE!>length<!>
|
z.<!UNSAFE_CALL!>length<!>
|
||||||
}
|
}
|
||||||
// First element is always analyzed
|
// First element is always analyzed
|
||||||
x.length
|
x.length
|
||||||
var xx = y ?: z
|
var xx = y ?: z
|
||||||
if ((xx!!.hashCode() == 0 && y!!.hashCode() == 1) || z!!.hashCode() == 2) {
|
if ((xx!!.hashCode() == 0 && y!!.hashCode() == 1) || z!!.hashCode() == 2) {
|
||||||
xx.length
|
xx.length
|
||||||
y.<!INAPPLICABLE_CANDIDATE!>length<!>
|
y.<!UNSAFE_CALL!>length<!>
|
||||||
z.<!INAPPLICABLE_CANDIDATE!>length<!>
|
z.<!UNSAFE_CALL!>length<!>
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
xx.length
|
xx.length
|
||||||
y.<!INAPPLICABLE_CANDIDATE!>length<!>
|
y.<!UNSAFE_CALL!>length<!>
|
||||||
// condition is false => z!! after or is called
|
// condition is false => z!! after or is called
|
||||||
z.length
|
z.length
|
||||||
}
|
}
|
||||||
@@ -35,16 +35,16 @@ fun foo(x: String?, y: String?, z: String?) {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
xx.length
|
xx.length
|
||||||
y.<!INAPPLICABLE_CANDIDATE!>length<!>
|
y.<!UNSAFE_CALL!>length<!>
|
||||||
z.<!INAPPLICABLE_CANDIDATE!>length<!>
|
z.<!UNSAFE_CALL!>length<!>
|
||||||
}
|
}
|
||||||
// First element is always analyzed
|
// First element is always analyzed
|
||||||
x.length
|
x.length
|
||||||
xx = y ?: z
|
xx = y ?: z
|
||||||
if (xx!!.hashCode() == 0 || y!!.hashCode() == 1 || z!!.hashCode() == 2) {
|
if (xx!!.hashCode() == 0 || y!!.hashCode() == 1 || z!!.hashCode() == 2) {
|
||||||
xx.length
|
xx.length
|
||||||
y.<!INAPPLICABLE_CANDIDATE!>length<!>
|
y.<!UNSAFE_CALL!>length<!>
|
||||||
z.<!INAPPLICABLE_CANDIDATE!>length<!>
|
z.<!UNSAFE_CALL!>length<!>
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// all three are called
|
// all three are called
|
||||||
|
|||||||
@@ -11,13 +11,13 @@ interface Order {
|
|||||||
fun foo(o: Any) {
|
fun foo(o: Any) {
|
||||||
val order = o as? Order
|
val order = o as? Order
|
||||||
if (order?.expired ?: false) {
|
if (order?.expired ?: false) {
|
||||||
order.<!INAPPLICABLE_CANDIDATE!>doSomething<!>()
|
order.<!UNSAFE_CALL!>doSomething<!>()
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
||||||
}
|
}
|
||||||
if (order?.notExpired() ?: false) {
|
if (order?.notExpired() ?: false) {
|
||||||
order.<!INAPPLICABLE_CANDIDATE!>doSomething<!>()
|
order.<!UNSAFE_CALL!>doSomething<!>()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -39,12 +39,12 @@ fun bar(o: Any) {
|
|||||||
|
|
||||||
fun baz(o: Boolean?) {
|
fun baz(o: Boolean?) {
|
||||||
if (o ?: false) {
|
if (o ?: false) {
|
||||||
o.<!INAPPLICABLE_CANDIDATE!>hashCode<!>()
|
o.<!UNSAFE_CALL!>hashCode<!>()
|
||||||
}
|
}
|
||||||
if (o ?: true) {
|
if (o ?: true) {
|
||||||
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
o.<!INAPPLICABLE_CANDIDATE!>hashCode<!>()
|
o.<!UNSAFE_CALL!>hashCode<!>()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -11,13 +11,13 @@ interface Order {
|
|||||||
fun foo(o: Any) {
|
fun foo(o: Any) {
|
||||||
val order = o as? Order
|
val order = o as? Order
|
||||||
if (order?.expired ?: false) {
|
if (order?.expired ?: false) {
|
||||||
order.<!INAPPLICABLE_CANDIDATE!>doSomething<!>()
|
order.<!UNSAFE_CALL!>doSomething<!>()
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
||||||
}
|
}
|
||||||
if (order?.notExpired() ?: false) {
|
if (order?.notExpired() ?: false) {
|
||||||
order.<!INAPPLICABLE_CANDIDATE!>doSomething<!>()
|
order.<!UNSAFE_CALL!>doSomething<!>()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -39,12 +39,12 @@ fun bar(o: Any) {
|
|||||||
|
|
||||||
fun baz(o: Boolean?) {
|
fun baz(o: Boolean?) {
|
||||||
if (o ?: false) {
|
if (o ?: false) {
|
||||||
o.<!INAPPLICABLE_CANDIDATE!>hashCode<!>()
|
o.<!UNSAFE_CALL!>hashCode<!>()
|
||||||
}
|
}
|
||||||
if (o ?: true) {
|
if (o ?: true) {
|
||||||
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
o.<!INAPPLICABLE_CANDIDATE!>hashCode<!>()
|
o.<!UNSAFE_CALL!>hashCode<!>()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
// Based on KT-9100
|
// Based on KT-9100
|
||||||
fun test(x: Any?, y: Any?): Any {
|
fun test(x: Any?, y: Any?): Any {
|
||||||
val z = x ?: y!!
|
val z = x ?: y!!
|
||||||
y.<!INAPPLICABLE_CANDIDATE!>hashCode<!>()
|
y.<!UNSAFE_CALL!>hashCode<!>()
|
||||||
// !! / ?. is necessary here, because y!! above may not be executed
|
// !! / ?. is necessary here, because y!! above may not be executed
|
||||||
y?.hashCode()
|
y?.hashCode()
|
||||||
y!!.hashCode()
|
y!!.hashCode()
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ class C {
|
|||||||
|
|
||||||
fun test(a: C?, nn: () -> Nothing?) {
|
fun test(a: C?, nn: () -> Nothing?) {
|
||||||
a ?: nn()
|
a ?: nn()
|
||||||
a.<!INAPPLICABLE_CANDIDATE!>foo<!>()
|
a.<!UNSAFE_CALL!>foo<!>()
|
||||||
|
|
||||||
a ?: return
|
a ?: return
|
||||||
a.foo()
|
a.foo()
|
||||||
|
|||||||
+1
-1
@@ -12,7 +12,7 @@ fun printMessages() {
|
|||||||
Message.HELLO.text!!
|
Message.HELLO.text!!
|
||||||
Message.HELLO.text.length
|
Message.HELLO.text.length
|
||||||
|
|
||||||
Message.NOTHING.text.<!INAPPLICABLE_CANDIDATE!>length<!>
|
Message.NOTHING.text.<!UNSAFE_CALL!>length<!>
|
||||||
|
|
||||||
Message.NOTHING.text!!
|
Message.NOTHING.text!!
|
||||||
Message.NOTHING.text.length
|
Message.NOTHING.text.length
|
||||||
|
|||||||
+1
-1
@@ -12,7 +12,7 @@ fun printMessages() {
|
|||||||
Message.HELLO.text!!
|
Message.HELLO.text!!
|
||||||
Message.HELLO.text.length
|
Message.HELLO.text.length
|
||||||
|
|
||||||
Message.NOTHING.text.<!INAPPLICABLE_CANDIDATE!>length<!>
|
Message.NOTHING.text.<!UNSAFE_CALL!>length<!>
|
||||||
|
|
||||||
Message.NOTHING.text!!
|
Message.NOTHING.text!!
|
||||||
Message.NOTHING.text.length
|
Message.NOTHING.text.length
|
||||||
|
|||||||
@@ -2,12 +2,12 @@ class D(val a: String, val b: Boolean)
|
|||||||
|
|
||||||
fun foo(p: Boolean, v: D?): String {
|
fun foo(p: Boolean, v: D?): String {
|
||||||
if (p && v!!.b) v.a
|
if (p && v!!.b) v.a
|
||||||
else v.<!INAPPLICABLE_CANDIDATE!>a<!>
|
else v.<!UNSAFE_CALL!>a<!>
|
||||||
if (p && v!! == D("?", false)) v.a
|
if (p && v!! == D("?", false)) v.a
|
||||||
else v.<!INAPPLICABLE_CANDIDATE!>a<!>
|
else v.<!UNSAFE_CALL!>a<!>
|
||||||
if (p || v!!.b) v.<!INAPPLICABLE_CANDIDATE!>a<!>
|
if (p || v!!.b) v.<!UNSAFE_CALL!>a<!>
|
||||||
else v.a
|
else v.a
|
||||||
if (p || v!! == D("?", false)) v.<!INAPPLICABLE_CANDIDATE!>a<!>
|
if (p || v!! == D("?", false)) v.<!UNSAFE_CALL!>a<!>
|
||||||
else v.a
|
else v.a
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,5 +9,5 @@ fun <T> T?.let(f: (T) -> Unit) {
|
|||||||
fun test(your: Your?) {
|
fun test(your: Your?) {
|
||||||
(your?.foo() as? Any)?.let {}
|
(your?.foo() as? Any)?.let {}
|
||||||
// strange smart cast to 'Your' at this point
|
// strange smart cast to 'Your' at this point
|
||||||
your.<!INAPPLICABLE_CANDIDATE!>hashCode<!>()
|
your.<!UNSAFE_CALL!>hashCode<!>()
|
||||||
}
|
}
|
||||||
@@ -7,6 +7,6 @@ fun foo() {
|
|||||||
var y: My? = My(42)
|
var y: My? = My(42)
|
||||||
if (y!!.x != null) {
|
if (y!!.x != null) {
|
||||||
y = My(null)
|
y = My(null)
|
||||||
y!!.x.<!INAPPLICABLE_CANDIDATE!>hashCode<!>()
|
y!!.x.<!UNSAFE_CALL!>hashCode<!>()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user