FIR checkers: report SMARTCAST_IMPOSSIBLE
This commit is contained in:
committed by
TeamCityServer
parent
2bb7ef9747
commit
ce767046eb
-15
@@ -1,15 +0,0 @@
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||
|
||||
interface Ctx
|
||||
class CtxImpl : Ctx {
|
||||
fun doJob(a: Int) {}
|
||||
fun doJob(s: String) {}
|
||||
}
|
||||
|
||||
open class Test(open val ctx: Ctx) {
|
||||
fun test() {
|
||||
when (ctx) {
|
||||
is CtxImpl -> ctx.<!UNRESOLVED_REFERENCE!>doJob<!>(2)
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||
|
||||
interface Ctx
|
||||
|
||||
-14
@@ -1,14 +0,0 @@
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||
|
||||
class A
|
||||
class B
|
||||
|
||||
fun A.foo(a: A) {}
|
||||
fun A.foo(b: B) {}
|
||||
var a: A? = null
|
||||
|
||||
fun smartCastInterference(b: B) {
|
||||
if (a != null) {
|
||||
a<!UNSAFE_CALL!>.<!>foo(b)
|
||||
}
|
||||
}
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||
|
||||
class A
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
class A<E> {
|
||||
fun foo(): E = TODO()
|
||||
}
|
||||
|
||||
class B(var a: A<*>?) {
|
||||
fun bar() {
|
||||
if (a != null) {
|
||||
a<!UNSAFE_CALL!>.<!>foo()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
class A<E> {
|
||||
fun foo(): E = TODO()
|
||||
}
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
open class A<E> {
|
||||
}
|
||||
|
||||
class B : A<String>() {
|
||||
fun foo() {}
|
||||
}
|
||||
|
||||
interface KI {
|
||||
val a: A<*>
|
||||
}
|
||||
|
||||
fun KI.bar() {
|
||||
if (a is B) {
|
||||
a.<!UNRESOLVED_REFERENCE!>foo<!>()
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
open class A<E> {
|
||||
}
|
||||
|
||||
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
// FIR_IDENTICAL
|
||||
class Test<E>(var c: Collection<E>) {
|
||||
fun test() {
|
||||
if (c is List<*>) {
|
||||
c.size // smartcast is unstable, but `size` is also available from `Collection`, so there should not be any error
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// !CHECK_TYPE
|
||||
|
||||
interface A {
|
||||
|
||||
+1
-1
@@ -10,6 +10,6 @@ fun failsWithClassCastException() {
|
||||
val sometimesNotInt: Any? by AlternatingDelegate()
|
||||
|
||||
if (sometimesNotInt is Int) {
|
||||
sometimesNotInt.<!UNRESOLVED_REFERENCE!>inc<!>()
|
||||
<!SMARTCAST_IMPOSSIBLE!>sometimesNotInt<!>.inc()
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -10,6 +10,6 @@ fun failsWithClassCastException() {
|
||||
val sometimesNotInt: Any? by AlternatingDelegate()
|
||||
|
||||
if (sometimesNotInt is Int) {
|
||||
sometimesNotInt.<!UNRESOLVED_REFERENCE!>inc<!>()
|
||||
<!SMARTCAST_IMPOSSIBLE!>sometimesNotInt<!>.inc()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ sealed class My(open val x: Int?) {
|
||||
init {
|
||||
if (x != null) {
|
||||
// Should be error: property is open
|
||||
x<!UNSAFE_CALL!>.<!>hashCode()
|
||||
<!SMARTCAST_IMPOSSIBLE!>x<!>.hashCode()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,7 @@ class Immutable(val x: String?) {
|
||||
|
||||
class Mutable(var y: String?) {
|
||||
fun foo(): String {
|
||||
if (y != null) return <!RETURN_TYPE_MISMATCH!>y<!>
|
||||
if (y != null) return <!SMARTCAST_IMPOSSIBLE!>y<!>
|
||||
return ""
|
||||
}
|
||||
}
|
||||
-13
@@ -1,13 +0,0 @@
|
||||
public class X {
|
||||
private val x : String? = null
|
||||
public val y: CharSequence?
|
||||
get() = x?.subSequence(0, 1)
|
||||
public fun fn(): Int {
|
||||
if (y != null)
|
||||
// With non-default getter smartcast is not possible
|
||||
return y<!UNSAFE_CALL!>.<!>length
|
||||
else
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
public class X {
|
||||
private val x : String? = null
|
||||
public val y: CharSequence?
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
public open class A() {
|
||||
public open val foo: Int? = 1
|
||||
}
|
||||
|
||||
infix fun Int.bar(i: Int) = i
|
||||
|
||||
fun test() {
|
||||
val p = A()
|
||||
// For open value properties, smart casts should not work
|
||||
if (p.foo is Int) p.foo <!UNSAFE_INFIX_CALL!>bar<!> 11
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
public open class A() {
|
||||
public open val foo: Int? = 1
|
||||
}
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
// MODULE: m1
|
||||
// FILE: a.kt
|
||||
|
||||
package a
|
||||
|
||||
public class X {
|
||||
public val x : String? = null
|
||||
}
|
||||
|
||||
// MODULE: m2(m1)
|
||||
// FILE: b.kt
|
||||
|
||||
package b
|
||||
|
||||
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
|
||||
else
|
||||
return 0
|
||||
}
|
||||
|
||||
// FILE: c.kt
|
||||
|
||||
package a
|
||||
|
||||
public fun X.gav(): Int {
|
||||
if (x != null)
|
||||
// Even if it's in the same package
|
||||
return x<!UNSAFE_CALL!>.<!>length
|
||||
else
|
||||
return 0
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// MODULE: m1
|
||||
// FILE: a.kt
|
||||
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
public class X {
|
||||
public var x : String? = null
|
||||
private var y: String? = "abc"
|
||||
public fun fn(): Int {
|
||||
if (x != null)
|
||||
// Smartcast is not possible for variable properties
|
||||
return x<!UNSAFE_CALL!>.<!>length
|
||||
else if (y != null)
|
||||
// Even if they are private
|
||||
return y<!UNSAFE_CALL!>.<!>length
|
||||
else
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
public class X {
|
||||
public var x : String? = null
|
||||
private var y: String? = "abc"
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
class Foo(var x: Int?) {
|
||||
init {
|
||||
if (x != null) {
|
||||
val y = x
|
||||
// Error: x is not stable, Type(y) = Int?
|
||||
x<!UNSAFE_CALL!>.<!>hashCode()
|
||||
y<!UNSAFE_CALL!>.<!>hashCode()
|
||||
if (y == x) {
|
||||
// Still error
|
||||
y<!UNSAFE_CALL!>.<!>hashCode()
|
||||
}
|
||||
if (x == null && y != x) {
|
||||
// Still error
|
||||
y<!UNSAFE_CALL!>.<!>hashCode()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
class Foo(var x: Int?) {
|
||||
init {
|
||||
if (x != null) {
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
class Bar {
|
||||
fun bar() {}
|
||||
}
|
||||
|
||||
class Foo(var x: Any) {
|
||||
init {
|
||||
if (x is Bar) {
|
||||
val y = x
|
||||
// Error: x is not stable, Type(y) = Any
|
||||
x.<!UNRESOLVED_REFERENCE!>bar<!>()
|
||||
y.<!UNRESOLVED_REFERENCE!>bar<!>()
|
||||
if (y == x) {
|
||||
// Still error
|
||||
y.<!UNRESOLVED_REFERENCE!>bar<!>()
|
||||
}
|
||||
if (x !is Bar && y != x) {
|
||||
// Still error
|
||||
y.<!UNRESOLVED_REFERENCE!>bar<!>()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
class Bar {
|
||||
fun bar() {}
|
||||
}
|
||||
|
||||
+1
-1
@@ -28,7 +28,7 @@ class UnstableReceiver {
|
||||
x<!UNSAFE_CALL!>.<!>inc()
|
||||
}
|
||||
else {
|
||||
x<!UNSAFE_CALL!>.<!>dec()
|
||||
<!SMARTCAST_IMPOSSIBLE!>x<!>.dec()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ fun valuesNullable(map: MutableMap<Int, String?>) {
|
||||
// ORIGINAL: fun merge(K, V, BiFunction<in V, in V, out V?>): V? defined in kotlin.collections.MutableMap
|
||||
// SUBSTITUTED: fun merge(Int, String, BiFunction<in String, in String, out String?>): String? defined in kotlin.collections.MutableMap
|
||||
map.merge(1, null) { old, new -> old + new }
|
||||
// OTHER_ERROR
|
||||
// UNSAFE_CALL_ERROR
|
||||
// ORIGINAL: fun merge(K, V, BiFunction<in V, in V, out V?>): V? defined in kotlin.collections.MutableMap
|
||||
// SUBSTITUTED: fun merge(Int, String, BiFunction<in String, in String, out String?>): String? defined in kotlin.collections.MutableMap
|
||||
}
|
||||
@@ -32,7 +32,7 @@ fun <T : Any> valuesTNotNull(map: MutableMap<Int, T>, newValue: T) {
|
||||
|
||||
fun <T : Any> valuesTNullable(map: MutableMap<Int, T?>, newValue: T?) {
|
||||
map.merge(1, newValue) { old, new -> new }
|
||||
// OTHER_ERROR
|
||||
// UNSAFE_CALL_ERROR
|
||||
// ORIGINAL: fun merge(K, V, BiFunction<in V, in V, out V?>): V? defined in kotlin.collections.MutableMap
|
||||
// SUBSTITUTED: fun merge(Int, T, BiFunction<in T, in T, out T?>): T? defined in kotlin.collections.MutableMap
|
||||
map.merge(1, newValue!!) { old, new -> new }
|
||||
|
||||
@@ -3,7 +3,7 @@ import java.util.*
|
||||
fun use() {
|
||||
val x: String? = "x"
|
||||
Optional.of(x)
|
||||
// OTHER_ERROR
|
||||
// UNSAFE_CALL_ERROR
|
||||
// ORIGINAL: fun <T : Any!> of(T): Optional<T> defined in java.util.Optional
|
||||
// SUBSTITUTED: fun <T : Any!> of(String): Optional<String> defined in java.util.Optional
|
||||
|
||||
|
||||
Reference in New Issue
Block a user