More precise diagnostics of smart cast impossible #KT-7240 Fixed
This commit is contained in:
@@ -6,7 +6,7 @@ fun foo(arg: Int?) {
|
||||
if (x == null) return
|
||||
run {
|
||||
// Not safe: x = null later in the owner
|
||||
x<!UNSAFE_CALL!>.<!>hashCode()
|
||||
<!SMARTCAST_IMPOSSIBLE!>x<!>.hashCode()
|
||||
}
|
||||
x = null
|
||||
}
|
||||
@@ -8,8 +8,8 @@ fun foo() {
|
||||
i = null
|
||||
}
|
||||
}
|
||||
i<!UNSAFE_CALL!>.<!>hashCode()
|
||||
<!SMARTCAST_IMPOSSIBLE!>i<!>.hashCode()
|
||||
Changing().bar()
|
||||
i<!UNSAFE_CALL!>.<!>hashCode()
|
||||
<!SMARTCAST_IMPOSSIBLE!>i<!>.hashCode()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,8 +7,8 @@ fun foo() {
|
||||
i = null
|
||||
return true
|
||||
}
|
||||
i<!UNSAFE_CALL!>.<!>hashCode()
|
||||
trans(<!TYPE_MISMATCH!>i<!>, ::can)
|
||||
i<!UNSAFE_CALL!>.<!>hashCode()
|
||||
<!SMARTCAST_IMPOSSIBLE!>i<!>.hashCode()
|
||||
trans(<!SMARTCAST_IMPOSSIBLE!>i<!>, ::can)
|
||||
<!SMARTCAST_IMPOSSIBLE!>i<!>.hashCode()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,6 +10,6 @@ fun foo() {
|
||||
i = null
|
||||
}
|
||||
}.bar()
|
||||
i<!UNSAFE_CALL!>.<!>hashCode()
|
||||
<!SMARTCAST_IMPOSSIBLE!>i<!>.hashCode()
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -6,10 +6,10 @@ fun foo(arg: Int?) {
|
||||
if (x == null) return
|
||||
run {
|
||||
// Unsafe because of owner modification
|
||||
x<!UNSAFE_CALL!>.<!>hashCode()
|
||||
<!SMARTCAST_IMPOSSIBLE!>x<!>.hashCode()
|
||||
x = null
|
||||
}
|
||||
if (x != null) x = 42
|
||||
// Unsafe because of lambda
|
||||
x<!UNSAFE_CALL!>.<!>hashCode()
|
||||
<!SMARTCAST_IMPOSSIBLE!>x<!>.hashCode()
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
class Immutable(val x: String?) {
|
||||
fun foo(): String {
|
||||
if (x != null) return <!DEBUG_INFO_SMARTCAST!>x<!>
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
class Mutable(var y: String?) {
|
||||
fun foo(): String {
|
||||
if (y != null) return <!SMARTCAST_IMPOSSIBLE!>y<!>
|
||||
return ""
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package
|
||||
|
||||
public final class Immutable {
|
||||
public constructor Immutable(/*0*/ x: kotlin.String?)
|
||||
public final val x: kotlin.String?
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public final fun foo(): kotlin.String
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public final class Mutable {
|
||||
public constructor Mutable(/*0*/ y: kotlin.String?)
|
||||
public final var y: kotlin.String?
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public final fun foo(): kotlin.String
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
@@ -5,7 +5,7 @@ public class X {
|
||||
public fun fn(): Int {
|
||||
if (y != null)
|
||||
// With non-default getter smartcast is not possible
|
||||
return y<!UNSAFE_CALL!>.<!>length
|
||||
return <!SMARTCAST_IMPOSSIBLE!>y<!>.length
|
||||
else
|
||||
return 0
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ class Example {
|
||||
|
||||
public fun foo(): String {
|
||||
// Smart cast is not possible if property is delegated
|
||||
return if (p != null) <!TYPE_MISMATCH!>p<!> else ""
|
||||
return if (p != null) <!SMARTCAST_IMPOSSIBLE!>p<!> else ""
|
||||
}
|
||||
|
||||
public fun bar(): String {
|
||||
|
||||
@@ -17,7 +17,7 @@ import a.X
|
||||
public fun X.gav(): Int {
|
||||
if (x != null)
|
||||
// Smart cast is not possible if definition is in another module
|
||||
return x<!UNSAFE_CALL!>.<!>length
|
||||
return <!SMARTCAST_IMPOSSIBLE!>x<!>.length
|
||||
else
|
||||
return 0
|
||||
}
|
||||
@@ -29,7 +29,7 @@ package a
|
||||
public fun X.gav(): Int {
|
||||
if (x != null)
|
||||
// Even if it's in the same package
|
||||
return x<!UNSAFE_CALL!>.<!>length
|
||||
return <!SMARTCAST_IMPOSSIBLE!>x<!>.length
|
||||
else
|
||||
return 0
|
||||
}
|
||||
|
||||
@@ -4,10 +4,10 @@ public class X {
|
||||
public fun fn(): Int {
|
||||
if (x != null)
|
||||
// Smartcast is not possible for variable properties
|
||||
return x<!UNSAFE_CALL!>.<!>length
|
||||
return <!SMARTCAST_IMPOSSIBLE!>x<!>.length
|
||||
else if (y != null)
|
||||
// Even if they are private
|
||||
return y<!UNSAFE_CALL!>.<!>length
|
||||
return <!SMARTCAST_IMPOSSIBLE!>y<!>.length
|
||||
else
|
||||
return 0
|
||||
}
|
||||
|
||||
+2
-2
@@ -7,11 +7,11 @@ public fun foo() {
|
||||
} else if (s == null) {
|
||||
return -2
|
||||
} else {
|
||||
return s<!UNSAFE_CALL!>.<!>length // Here smartcast is possible, at least in principle
|
||||
return <!SMARTCAST_IMPOSSIBLE!>s<!>.length // Here smartcast is possible, at least in principle
|
||||
}
|
||||
}
|
||||
if (s != null) {
|
||||
System.out.println(closure())
|
||||
System.out.println(s<!UNSAFE_CALL!>.<!>length) // Here smartcast is not possible due to a closure predecessor
|
||||
System.out.println(<!SMARTCAST_IMPOSSIBLE!>s<!>.length) // Here smartcast is not possible due to a closure predecessor
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -8,7 +8,7 @@ fun IntArray.forEachIndexed( op: (i: Int, value: Int) -> Unit) {
|
||||
fun max(a: IntArray): Int? {
|
||||
var maxI: Int? = null
|
||||
a.forEachIndexed { i, value ->
|
||||
if (maxI == null || value >= a[<!TYPE_MISMATCH!>maxI<!>])
|
||||
if (maxI == null || value >= a[<!SMARTCAST_IMPOSSIBLE!>maxI<!>])
|
||||
maxI = i
|
||||
}
|
||||
return maxI
|
||||
|
||||
Reference in New Issue
Block a user