FIR: report UNSAFE_CALL on dot when possible
This commit is contained in:
@@ -2,5 +2,5 @@ fun calc(x: List<String>?): Int {
|
||||
// After KT-5840 fix !! assertion should become unnecessary here
|
||||
x?.get(x!!.size - 1)
|
||||
// x?. or x!! above should not provide smart cast here
|
||||
return x.<!UNSAFE_CALL!>size<!>
|
||||
return x<!UNSAFE_CALL!>.<!>size
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
fun calc(x: List<String>?): Int {
|
||||
// x is not-null only inside subList
|
||||
x?.subList(0, x.size - 1).<!UNSAFE_CALL!>get<!>(x.<!UNSAFE_CALL!>size<!>)
|
||||
x?.subList(0, x.size - 1)<!UNSAFE_CALL!>.<!>get(x<!UNSAFE_CALL!>.<!>size)
|
||||
return x!!.size
|
||||
}
|
||||
|
||||
@@ -2,5 +2,5 @@ fun calc(x: List<String>?): Int {
|
||||
// x should be non-null in arguments list, including inner call
|
||||
x?.get(x.get(x.size - 1).length)
|
||||
// but not also here!
|
||||
return x.<!UNSAFE_CALL!>size<!>
|
||||
return x<!UNSAFE_CALL!>.<!>size
|
||||
}
|
||||
|
||||
+1
-1
@@ -4,5 +4,5 @@ fun calc(x: String?, y: String?): Int {
|
||||
// Smart cast because of y!! in receiver
|
||||
x?.subSequence(y!!.subSequence(0, 1).length, y.length)
|
||||
// No smart cast possible
|
||||
return y.<!UNSAFE_CALL!>length<!>
|
||||
return y<!UNSAFE_CALL!>.<!>length
|
||||
}
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
// See KT-11007: Wrong smart cast to not-null type after safe calls in if / when expression
|
||||
|
||||
val String.copy: String
|
||||
get() = this
|
||||
|
||||
fun foo() {
|
||||
val s: String? = null
|
||||
val ss = if (true) {
|
||||
s?.length
|
||||
} else {
|
||||
s?.length
|
||||
}
|
||||
ss.<!UNSAFE_CALL!>hashCode<!>() // Smart-cast to Int, should be unsafe call
|
||||
val sss = if (true) {
|
||||
s?.copy
|
||||
}
|
||||
else {
|
||||
s?.copy
|
||||
}
|
||||
sss.<!UNSAFE_CALL!>length<!>
|
||||
}
|
||||
|
||||
class My {
|
||||
val String.copy2: String
|
||||
get() = this
|
||||
|
||||
fun foo() {
|
||||
val s: String? = null
|
||||
val ss = if (true) {
|
||||
s?.length
|
||||
} else {
|
||||
s?.length
|
||||
}
|
||||
ss.<!UNSAFE_CALL!>hashCode<!>()
|
||||
val sss = if (true) {
|
||||
s?.copy2
|
||||
}
|
||||
else {
|
||||
s?.copy2
|
||||
}
|
||||
sss.<!UNSAFE_CALL!>length<!>
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// See KT-11007: Wrong smart cast to not-null type after safe calls in if / when expression
|
||||
|
||||
val String.copy: String
|
||||
|
||||
-13
@@ -1,13 +0,0 @@
|
||||
// See KT-10056
|
||||
class Foo(val bar: String)
|
||||
|
||||
fun test(foo: Foo?) {
|
||||
foo?.bar.let {
|
||||
// Error, foo?.bar is nullable
|
||||
it.<!UNSAFE_CALL!>length<!>
|
||||
// Error, foo is nullable
|
||||
foo.<!UNSAFE_CALL!>bar<!>.length
|
||||
// Correct
|
||||
foo?.bar?.length
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// See KT-10056
|
||||
class Foo(val bar: String)
|
||||
|
||||
|
||||
Vendored
+6
-6
@@ -11,22 +11,22 @@ fun String.notNullLet(f: (String) -> Unit) = f(this)
|
||||
fun test(foo: Foo?) {
|
||||
foo?.bar?.gav.let {
|
||||
// Error, foo?.bar?.gav is nullable
|
||||
it.<!UNSAFE_CALL!>length<!>
|
||||
it<!UNSAFE_CALL!>.<!>length
|
||||
// Error, foo is nullable
|
||||
foo.<!UNSAFE_CALL!>bar<!>.gav.length
|
||||
foo<!UNSAFE_CALL!>.<!>bar.gav.length
|
||||
// Correct
|
||||
foo?.bar?.gav?.length
|
||||
}
|
||||
foo?.bar?.gav.call { it }?.notNullLet {
|
||||
foo.<!UNSAFE_CALL!>hashCode<!>()
|
||||
foo.<!UNSAFE_CALL!>bar<!>.hashCode()
|
||||
foo<!UNSAFE_CALL!>.<!>hashCode()
|
||||
foo<!UNSAFE_CALL!>.<!>bar.hashCode()
|
||||
}
|
||||
}
|
||||
|
||||
fun testNotNull(foo: Foo) {
|
||||
val s: String? = ""
|
||||
foo.baz(s!!)?.gav.let {
|
||||
it.<!UNSAFE_CALL!>length<!>
|
||||
it<!UNSAFE_CALL!>.<!>length
|
||||
// Ok because of foo.
|
||||
s.length.hashCode()
|
||||
}
|
||||
@@ -35,7 +35,7 @@ fun testNotNull(foo: Foo) {
|
||||
fun testNullable(foo: Foo?) {
|
||||
val s: String? = ""
|
||||
foo?.baz(s!!)?.gav.let {
|
||||
it.<!UNSAFE_CALL!>length<!>
|
||||
it<!UNSAFE_CALL!>.<!>length
|
||||
// Ok because of foo?.
|
||||
s?.length?.hashCode()
|
||||
}
|
||||
|
||||
Vendored
-25
@@ -1,25 +0,0 @@
|
||||
// FILE: Foo.java
|
||||
public class Foo {
|
||||
public String bar;
|
||||
|
||||
private Foo(String bar) {
|
||||
this.bar = bar;
|
||||
}
|
||||
|
||||
public static Foo create(String bar) {
|
||||
return new Foo(bar);
|
||||
}
|
||||
}
|
||||
|
||||
// FILE: Test.kt
|
||||
fun test() {
|
||||
val foo = Foo.create(null)
|
||||
foo?.bar.let {
|
||||
// Error, foo?.bar is nullable
|
||||
it.<!UNSAFE_CALL!>length<!>
|
||||
// Foo is nullable but flexible, so call is considered safe here
|
||||
foo.bar.length
|
||||
// Correct
|
||||
foo?.bar?.length
|
||||
}
|
||||
}
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// FILE: Foo.java
|
||||
public class Foo {
|
||||
public String bar;
|
||||
|
||||
+4
-4
@@ -18,7 +18,7 @@ fun kt6840_2(s: String?) {
|
||||
|
||||
fun kt1635(s: String?) {
|
||||
s?.hashCode()!!
|
||||
s.<!UNSAFE_CALL!>hashCode<!>()
|
||||
s<!UNSAFE_CALL!>.<!>hashCode()
|
||||
}
|
||||
|
||||
fun kt2127() {
|
||||
@@ -80,7 +80,7 @@ fun useA(a: A): Int = a.hashCode()
|
||||
|
||||
fun kt7491_2() {
|
||||
val a = getA()
|
||||
(a?.let { useA(a) } ?: a.<!UNSAFE_CALL!>y<!> ).toString()
|
||||
(a?.let { useA(a) } ?: a<!UNSAFE_CALL!>.<!>y ).toString()
|
||||
}
|
||||
|
||||
fun String.correct() = true
|
||||
@@ -88,7 +88,7 @@ fun String.correct() = true
|
||||
fun kt8492(s: String?) {
|
||||
if (s?.correct() ?: false) {
|
||||
// To be supported
|
||||
s.<!UNSAFE_CALL!>length<!>
|
||||
s<!UNSAFE_CALL!>.<!>length
|
||||
}
|
||||
}
|
||||
|
||||
@@ -118,7 +118,7 @@ class Wrapper {
|
||||
fun falsePositive(w: Wrapper) {
|
||||
if (w.unwrap() != null) {
|
||||
// Here we should NOT have smart cast
|
||||
w.unwrap().<!UNSAFE_CALL!>length<!>
|
||||
w.unwrap()<!UNSAFE_CALL!>.<!>length
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,5 +2,5 @@ fun calc(x: List<String>?): Int {
|
||||
// x should be non-null in arguments list
|
||||
x?.get(x.size - 1)
|
||||
// but not also here!
|
||||
return x.<!UNSAFE_CALL!>size<!>
|
||||
return x<!UNSAFE_CALL!>.<!>size
|
||||
}
|
||||
|
||||
@@ -2,5 +2,5 @@ fun calc(x: List<String>?): Int {
|
||||
// x should be non-null in arguments list
|
||||
x?.subList(x.size - 1, x.size)
|
||||
// but not also here!
|
||||
return x.<!UNSAFE_CALL!>size<!>
|
||||
return x<!UNSAFE_CALL!>.<!>size
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user