[FIR] Fix missing USELESS_CAST
`FirUselessTypeOperationCallChecker` always checks exact types matching for `as` operator Simplify code of cast checker and utils ^KT-56629 Fixed ^KT-56615 Fixed ^KT-59820 Fixed
This commit is contained in:
committed by
Space Team
parent
2f8026f335
commit
d50c6f1b6d
+2
-2
@@ -10,8 +10,8 @@ fun test() : Unit {
|
||||
checkSubtype<Int>(y <!USELESS_CAST!>as Int<!>)
|
||||
checkSubtype<Int?>(x as Int?)
|
||||
checkSubtype<Int?>(y as Int?)
|
||||
checkSubtype<Int?>(x as? Int)
|
||||
checkSubtype<Int?>(y as? Int)
|
||||
checkSubtype<Int?>(x <!USELESS_CAST!>as? Int<!>)
|
||||
checkSubtype<Int?>(y <!USELESS_CAST!>as? Int<!>)
|
||||
checkSubtype<Int?>(x as? Int?)
|
||||
checkSubtype<Int?>(y as? Int?)
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ fun test(x: Int?) {
|
||||
foo(x as? Number)
|
||||
|
||||
if (x is Int) {
|
||||
val b = x as? Int
|
||||
val b = x <!USELESS_CAST!>as? Int<!>
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
fun asCall() {
|
||||
1 <!USELESS_CAST!>as Int<!>
|
||||
1 <!CAST_NEVER_SUCCEEDS!>as<!> Byte
|
||||
1 <!CAST_NEVER_SUCCEEDS!>as<!> Short
|
||||
1 <!CAST_NEVER_SUCCEEDS!>as<!> Long
|
||||
1 <!CAST_NEVER_SUCCEEDS!>as<!> Char
|
||||
1 <!CAST_NEVER_SUCCEEDS!>as<!> Double
|
||||
1 <!CAST_NEVER_SUCCEEDS!>as<!> Float
|
||||
|
||||
1.0 <!CAST_NEVER_SUCCEEDS!>as<!> Int
|
||||
1.0 <!CAST_NEVER_SUCCEEDS!>as<!> Byte
|
||||
1.0 <!CAST_NEVER_SUCCEEDS!>as<!> Short
|
||||
1.0 <!CAST_NEVER_SUCCEEDS!>as<!> Long
|
||||
1.0 <!CAST_NEVER_SUCCEEDS!>as<!> Char
|
||||
1.0 <!USELESS_CAST!>as Double<!>
|
||||
1.0 <!CAST_NEVER_SUCCEEDS!>as<!> Float
|
||||
|
||||
1f <!CAST_NEVER_SUCCEEDS!>as<!> Int
|
||||
1f <!CAST_NEVER_SUCCEEDS!>as<!> Byte
|
||||
1f <!CAST_NEVER_SUCCEEDS!>as<!> Short
|
||||
1f <!CAST_NEVER_SUCCEEDS!>as<!> Long
|
||||
1f <!CAST_NEVER_SUCCEEDS!>as<!> Char
|
||||
1f <!CAST_NEVER_SUCCEEDS!>as<!> Double
|
||||
1f <!USELESS_CAST!>as Float<!>
|
||||
}
|
||||
|
||||
fun asSafe() {
|
||||
1 as? Int
|
||||
1 <!CAST_NEVER_SUCCEEDS!>as?<!> Byte
|
||||
1 <!CAST_NEVER_SUCCEEDS!>as?<!> Short
|
||||
1 <!CAST_NEVER_SUCCEEDS!>as?<!> Long
|
||||
1 <!CAST_NEVER_SUCCEEDS!>as?<!> Char
|
||||
1 <!CAST_NEVER_SUCCEEDS!>as?<!> Double
|
||||
1 <!CAST_NEVER_SUCCEEDS!>as?<!> Float
|
||||
|
||||
1.0 <!CAST_NEVER_SUCCEEDS!>as?<!> Int
|
||||
1.0 <!CAST_NEVER_SUCCEEDS!>as?<!> Byte
|
||||
1.0 <!CAST_NEVER_SUCCEEDS!>as?<!> Short
|
||||
1.0 <!CAST_NEVER_SUCCEEDS!>as?<!> Long
|
||||
1.0 <!CAST_NEVER_SUCCEEDS!>as?<!> Char
|
||||
1.0 as? Double
|
||||
1.0 <!CAST_NEVER_SUCCEEDS!>as?<!> Float
|
||||
|
||||
1f <!CAST_NEVER_SUCCEEDS!>as?<!> Int
|
||||
1f <!CAST_NEVER_SUCCEEDS!>as?<!> Byte
|
||||
1f <!CAST_NEVER_SUCCEEDS!>as?<!> Short
|
||||
1f <!CAST_NEVER_SUCCEEDS!>as?<!> Long
|
||||
1f <!CAST_NEVER_SUCCEEDS!>as?<!> Char
|
||||
1f <!CAST_NEVER_SUCCEEDS!>as?<!> Double
|
||||
1f as? Float
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
fun asCall() {
|
||||
1 <!USELESS_CAST!>as Int<!>
|
||||
1 <!CAST_NEVER_SUCCEEDS!>as<!> Byte
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
// ISSUE: KT-56629, KT-56615
|
||||
|
||||
class Klass
|
||||
fun foo(arg: Klass) {
|
||||
arg <!USELESS_CAST!>as Klass<!>
|
||||
arg <!USELESS_CAST!>as? Klass<!>
|
||||
}
|
||||
|
||||
fun test_1(a: Any?) {
|
||||
(a as String?)!!
|
||||
a.length
|
||||
(a <!USELESS_CAST!>as? String<!>)!!
|
||||
a.length
|
||||
}
|
||||
|
||||
fun test_3(a: Any?) {
|
||||
a as String
|
||||
a <!USELESS_CAST!>as String<!>
|
||||
}
|
||||
|
||||
fun test_4(a: Any?) {
|
||||
a as String
|
||||
a <!USELESS_CAST!>as? String<!>
|
||||
}
|
||||
|
||||
fun test_5(a: Any?) {
|
||||
(a as? String)!!
|
||||
a.length
|
||||
(a <!USELESS_CAST!>as String<!>)
|
||||
}
|
||||
|
||||
fun test_6(a: Any?) {
|
||||
(a as? String)!!
|
||||
a.length
|
||||
(a <!USELESS_CAST!>as? String<!>)
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
// ISSUE: KT-56629, KT-56615
|
||||
|
||||
class Klass
|
||||
fun foo(arg: Klass) {
|
||||
arg <!USELESS_CAST!>as Klass<!>
|
||||
arg <!USELESS_CAST!>as? Klass<!>
|
||||
}
|
||||
|
||||
fun test_1(a: Any?) {
|
||||
(a as String?)!!
|
||||
a<!UNSAFE_CALL!>.<!>length
|
||||
(a <!USELESS_CAST!>as? String<!>)!!
|
||||
<!DEBUG_INFO_SMARTCAST!>a<!>.length
|
||||
}
|
||||
|
||||
fun test_3(a: Any?) {
|
||||
a as String
|
||||
a <!USELESS_CAST!>as String<!>
|
||||
}
|
||||
|
||||
fun test_4(a: Any?) {
|
||||
a as String
|
||||
a <!USELESS_CAST!>as? String<!>
|
||||
}
|
||||
|
||||
fun test_5(a: Any?) {
|
||||
(a as? String)!!
|
||||
<!DEBUG_INFO_SMARTCAST!>a<!>.length
|
||||
(a <!USELESS_CAST!>as String<!>)
|
||||
}
|
||||
|
||||
fun test_6(a: Any?) {
|
||||
(a as? String)!!
|
||||
<!DEBUG_INFO_SMARTCAST!>a<!>.length
|
||||
(a <!USELESS_CAST!>as? String<!>)
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER, -SENSELESS_COMPARISON, -DEBUG_INFO_SMARTCAST
|
||||
|
||||
fun <T: Any?> test1(t: Any?): Any {
|
||||
return t <!UNCHECKED_CAST!>as T<!> ?: ""
|
||||
}
|
||||
|
||||
fun <T: Any> test2(t: Any?): Any {
|
||||
return t <!UNCHECKED_CAST!>as T<!> <!USELESS_ELVIS!>?: ""<!>
|
||||
}
|
||||
|
||||
fun <T: Any?> test3(t: Any?): Any {
|
||||
if (t != null) {
|
||||
return t <!USELESS_ELVIS!>?: ""<!>
|
||||
}
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
fun takeNotNull(s: String) {}
|
||||
fun <T> notNull(): T = TODO()
|
||||
fun <T> nullable(): T? = null
|
||||
fun <T> dependOn(x: T) = x
|
||||
|
||||
fun test() {
|
||||
takeNotNull(notNull() ?: "")
|
||||
takeNotNull(nullable() ?: "")
|
||||
|
||||
val x: String? = null
|
||||
takeNotNull(dependOn(x) ?: "")
|
||||
takeNotNull(dependOn(dependOn(x)) ?: "")
|
||||
takeNotNull(dependOn(dependOn(x as String)) <!USELESS_ELVIS!>?: ""<!>)
|
||||
|
||||
if (x != null) {
|
||||
takeNotNull(dependOn(x) <!USELESS_ELVIS!>?: ""<!>)
|
||||
takeNotNull(dependOn(dependOn(x)) <!USELESS_ELVIS!>?: ""<!>)
|
||||
takeNotNull(dependOn(dependOn(x) <!USELESS_CAST!>as? String<!>) ?: "")
|
||||
}
|
||||
|
||||
takeNotNull(bar()!!)
|
||||
}
|
||||
|
||||
inline fun <reified T : Any> reifiedNull(): T? = null
|
||||
|
||||
fun testFrom13648() {
|
||||
takeNotNull(reifiedNull() ?: "")
|
||||
}
|
||||
|
||||
fun bar() = <!UNRESOLVED_REFERENCE!>unresolved<!>
|
||||
@@ -1,4 +1,3 @@
|
||||
// FIR_IDENTICAL
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER, -SENSELESS_COMPARISON, -DEBUG_INFO_SMARTCAST
|
||||
|
||||
fun <T: Any?> test1(t: Any?): Any {
|
||||
|
||||
@@ -13,7 +13,7 @@ fun g(a: SomeClass?) {
|
||||
// 'a' can be cast to SomeSubClass
|
||||
a.hashCode()
|
||||
a.foo
|
||||
(a as? SomeSubClass)<!UNSAFE_CALL!>.<!>foo
|
||||
(a <!USELESS_CAST!>as? SomeSubClass<!>)<!UNSAFE_CALL!>.<!>foo
|
||||
(a <!USELESS_CAST!>as SomeSubClass<!>).foo
|
||||
}
|
||||
val b = (a as? SomeSubClass)?.foo
|
||||
@@ -21,7 +21,7 @@ fun g(a: SomeClass?) {
|
||||
// 'a' can be cast to SomeSubClass
|
||||
a.hashCode()
|
||||
a.foo
|
||||
(a as? SomeSubClass)<!UNSAFE_CALL!>.<!>foo
|
||||
(a <!USELESS_CAST!>as? SomeSubClass<!>)<!UNSAFE_CALL!>.<!>foo
|
||||
(a <!USELESS_CAST!>as SomeSubClass<!>).foo
|
||||
}
|
||||
val c = a as? SomeSubClass
|
||||
@@ -29,7 +29,7 @@ fun g(a: SomeClass?) {
|
||||
// 'a' and 'c' can be cast to SomeSubClass
|
||||
a.hashCode()
|
||||
a.foo
|
||||
(a as? SomeSubClass)<!UNSAFE_CALL!>.<!>foo
|
||||
(a <!USELESS_CAST!>as? SomeSubClass<!>)<!UNSAFE_CALL!>.<!>foo
|
||||
c.hashCode()
|
||||
c.foo
|
||||
}
|
||||
|
||||
@@ -60,7 +60,7 @@ fun f(a: SomeClass?) {
|
||||
// 'c' can be cast to SomeSubClass
|
||||
aa.hashCode()
|
||||
aa.foo
|
||||
(aa as? SomeSubClass)<!UNSAFE_CALL!>.<!>foo
|
||||
(aa <!USELESS_CAST!>as? SomeSubClass<!>)<!UNSAFE_CALL!>.<!>foo
|
||||
c.hashCode()
|
||||
c.foo
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user