FIR checker: warn useless as and is

This commit is contained in:
Jinseong Jeon
2021-04-28 22:32:51 -07:00
committed by TeamCityServer
parent 19d939c36e
commit e2dc21da90
141 changed files with 417 additions and 543 deletions
+1 -1
View File
@@ -7,7 +7,7 @@ fun test() : Unit {
checkSubtype<Int?>(x)
checkSubtype<Int>(y)
checkSubtype<Int>(x as Int)
checkSubtype<Int>(y as Int)
checkSubtype<Int>(y <!USELESS_CAST!>as Int<!>)
checkSubtype<Int?>(x as Int?)
checkSubtype<Int?>(y as Int?)
checkSubtype<Int?>(x as? Int)
+1 -1
View File
@@ -33,7 +33,7 @@ fun test() {
checkSubtype<Float>(<!ARGUMENT_TYPE_MISMATCH!>1<!>)
1 as Byte
1 as Int
1 <!USELESS_CAST!>as Int<!>
0xff as Long
1.1 as Int
+4 -4
View File
@@ -1,21 +1,21 @@
// FILE: KotlinFile.kt
fun test() {
if (1 is Int) {
if (<!USELESS_IS_CHECK!>1 is Int<!>) {
if (1 is Boolean) {
}
}
A.create() is A
A.create() is A?
<!USELESS_IS_CHECK!>A.create() is A?<!>
<!UNRESOLVED_REFERENCE!>unresolved<!> is A
<!UNRESOLVED_REFERENCE!>unresolved<!> is A?
val x = foo()
x as String
x is String
<!USELESS_IS_CHECK!>x is String<!>
}
fun foo(): Any = ""
@@ -23,4 +23,4 @@ fun foo(): Any = ""
// FILE: A.java
class A {
static A create() { return null; }
}
}
@@ -45,10 +45,10 @@ fun test(a: Any) {
.0fin a
.0<!UNRESOLVED_REFERENCE!>din<!> a
1is Any
<!USELESS_IS_CHECK!>1is Any<!>
1as Any
1as? Any
1!is Any
<!USELESS_IS_CHECK!>1!is Any<!>
1!in a
}
}
@@ -31,8 +31,8 @@ fun test(a: Any) {
a !in's'
a !in<!EMPTY_CHARACTER_LITERAL!>''<!>
if("s"is Any) {}
if("s"is Any) {}
if(<!USELESS_IS_CHECK!>"s"is Any<!>) {}
if(<!USELESS_IS_CHECK!>"s"is Any<!>) {}
test("s"as Any)
a foo""<!SYNTAX!>1<!>
@@ -26,7 +26,7 @@ fun foo() {
}
fun bar(a: Ann = Ann()) {
if (a is Ann) {}
if (<!USELESS_IS_CHECK!>a is Ann<!>) {}
}
operator fun String.invoke() {}
@@ -25,8 +25,8 @@ fun testRun() {
}
run<Int?> {
1 as Int
1 as Int
1 <!USELESS_CAST!>as Int<!>
1 <!USELESS_CAST!>as Int<!>
}
runWithoutReturn {
@@ -4,7 +4,7 @@ fun test() {
val a = 1 as Any?
val b: Number = 1 as Number
val c = null as String?
val d: Number = 1 as Int
val d: Number = 1 <!USELESS_CAST!>as Int<!>
}
val c1 get() = 1 as Number
@@ -14,4 +14,4 @@ val d: Number
get() {
1 as Number
return 1 as Number
}
}
@@ -18,9 +18,9 @@ public class Foo {
fun test() {
Foo.create() as Foo
Foo.createN() as Foo
Foo.createNN() as Foo
Foo.createNN() <!USELESS_CAST!>as Foo<!>
Foo.create() as Foo?
Foo.createN() as Foo?
Foo.create() <!USELESS_CAST!>as Foo?<!>
Foo.createN() <!USELESS_CAST!>as Foo?<!>
Foo.createNN() as Foo?
}
}
@@ -1,5 +0,0 @@
open class Base<A>
class Some: Base<Int>()
// a is Some => a is Base<Int>
fun f(a: Some) = a is Base<Int>
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
open class Base<A>
class Some: Base<Int>()
@@ -1,8 +0,0 @@
open class A
open class B: A()
open class Base<in T>
class SubBase: Base<A>()
// f is SubBase => f is Base<A> => (Base<Contravariant T>, B <: A) f is Base<B>
fun test(f: SubBase) = f is Base<B>
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
open class A
open class B: A()
@@ -1,8 +0,0 @@
open class A
open class B: A()
open class Base<out T>
class SubBase: Base<B>()
// f is SubBase => (SubBase <: Base<B>) f is Base<B> => (B <: A, Base<Covariant T> => SubBase <: Base<A>) f is Base<A>
fun test(f: SubBase) = f is Base<A>
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
open class A
open class B: A()
@@ -1 +0,0 @@
fun f(a: MutableList<out Number>) = a is MutableList<out Any>
@@ -1 +1,2 @@
// FIR_IDENTICAL
fun f(a: MutableList<out Number>) = <!USELESS_IS_CHECK!>a is MutableList<out Any><!>
@@ -1 +0,0 @@
fun f(a: MutableList<String>) = a is MutableList<out CharSequence>
@@ -1 +1,2 @@
// FIR_IDENTICAL
fun f(a: MutableList<String>) = <!USELESS_IS_CHECK!>a is MutableList<out CharSequence><!>
@@ -1 +0,0 @@
fun f(a: List<Number>) = a is List<Any>
@@ -1 +1,2 @@
// FIR_IDENTICAL
fun f(a: List<Number>) = <!USELESS_IS_CHECK!>a is List<Any><!>
@@ -1 +0,0 @@
fun <T> testing(a: T) = a is T
@@ -1 +1,2 @@
// FIR_IDENTICAL
fun <T> testing(a: T) = <!USELESS_IS_CHECK!>a is T<!>
@@ -1,14 +1,14 @@
fun <T, S : T> test(x: T?, y: S, z: T) {
x is T
x is T?
<!USELESS_IS_CHECK!>x is T?<!>
y is T
y is S
y is T?
y is S?
<!USELESS_IS_CHECK!>y is T<!>
<!USELESS_IS_CHECK!>y is S<!>
<!USELESS_IS_CHECK!>y is T?<!>
<!USELESS_IS_CHECK!>y is S?<!>
z is T
z is T?
<!USELESS_IS_CHECK!>z is T<!>
<!USELESS_IS_CHECK!>z is T?<!>
null as T
null as T?
@@ -22,6 +22,6 @@ inline fun <reified T> test(x: T?) {
}
fun <T> foo(x: List<T>, y: List<T>?) {
x is List<T>
<!USELESS_IS_CHECK!>x is List<T><!>
y is List<T>
}
}
@@ -2,15 +2,15 @@
// !DIAGNOSTICS: -UNUSED_PARAMETER, -UNUSED_VARIABLE
fun test(x: Int?) {
val a1 = x as? Int
val a2 = x as? Int?
val a1 = x <!USELESS_CAST!>as? Int<!>
val a2 = x <!USELESS_CAST!>as? Int?<!>
val a3 = x as? Number
val a4 = x as? Number?
val a5: Int? = x as? Int
val a6: Number? = x as? Int
val a5: Int? = x <!USELESS_CAST!>as? Int<!>
val a6: Number? = x <!USELESS_CAST!>as? Int<!>
val a7: Number? = 1 as? Number
run { x as? Int }
run { x <!USELESS_CAST!>as? Int<!> }
run { x as? Number }
foo(x as? Number)
@@ -22,17 +22,17 @@ public class JavaClass {
// FILE: test.kt
fun <T, S: Any> test(x1: T, x2: T?, y1: S, y2: S?) {
x1 is T?
x2 is T?
y1 is S?
y2 is S?
<!USELESS_IS_CHECK!>x1 is T?<!>
<!USELESS_IS_CHECK!>x2 is T?<!>
<!USELESS_IS_CHECK!>y1 is S?<!>
<!USELESS_IS_CHECK!>y2 is S?<!>
val f1 = JavaClass.foo()
f1 is Int?
<!USELESS_IS_CHECK!>f1 is Int?<!>
val f2 = JavaClass.fooN()
f2 is Int?
<!USELESS_IS_CHECK!>f2 is Int?<!>
val f3 = JavaClass.fooNN()
f3 is Int?
<!USELESS_IS_CHECK!>f3 is Int?<!>
}
+4 -4
View File
@@ -1,5 +1,5 @@
fun asCall() {
1 as Int
1 <!USELESS_CAST!>as Int<!>
1 as Byte
1 as Short
1 as Long
@@ -12,7 +12,7 @@ fun asCall() {
1.0 as Short
1.0 as Long
1.0 as Char
1.0 as Double
1.0 <!USELESS_CAST!>as Double<!>
1.0 as Float
1f as Int
@@ -21,7 +21,7 @@ fun asCall() {
1f as Long
1f as Char
1f as Double
1f as Float
1f <!USELESS_CAST!>as Float<!>
}
fun asSafe() {
@@ -48,4 +48,4 @@ fun asSafe() {
1f as? Char
1f as? Double
1f as? Float
}
}
@@ -1,20 +0,0 @@
open class C {
}
fun C.foo() {}
open class X {
companion object : C() {}
}
open class Y {
companion object : C() {}
}
fun bar() {
val x = X
x.foo()
X.foo()
(X as C).foo()
((if (1<2) X else Y) as C).foo()
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
open class C {
}
@@ -33,8 +33,18 @@ inline fun <reified T> case_5() {
val z = x.test()
if (z is T) {
if (<!USELESS_IS_CHECK!>z is T<!>) {
// z is {T!! & T!!} (smart cast from T)
<!UNRESOLVED_REFERENCE!>println<!>(z)
}
val a = object<A> {
fun test() = 42 as <!UNRESOLVED_REFERENCE!>A<!>
}
val b = a.test()
if (a is T) {
<!UNRESOLVED_REFERENCE!>println<!>(a)
}
}
@@ -37,4 +37,14 @@ inline fun <reified T> case_5() {
// z is {T!! & T!!} (smart cast from T)
<!UNRESOLVED_REFERENCE!>println<!>(z)
}
val a = object<!TYPE_PARAMETERS_IN_ANONYMOUS_OBJECT!><A><!> {
fun test() = 42 <!UNCHECKED_CAST!>as A<!>
}
val b = a.test()
if (a is T) {
<!UNRESOLVED_REFERENCE!>println<!>(a)
}
}
@@ -33,8 +33,18 @@ inline fun <reified T> case_5() {
val z = x.test()
if (z is T) {
if (<!USELESS_IS_CHECK!>z is T<!>) {
// z is {T!! & T!!} (smart cast from T)
<!UNRESOLVED_REFERENCE!>println<!>(z)
}
val a = object<A> {
fun test() = 42 as <!UNRESOLVED_REFERENCE!>A<!>
}
val b = a.test()
if (a is T) {
<!UNRESOLVED_REFERENCE!>println<!>(a)
}
}
@@ -37,4 +37,14 @@ inline fun <reified T> case_5() {
// z is {T!! & T!!} (smart cast from T)
<!UNRESOLVED_REFERENCE!>println<!>(z)
}
val a = object<!TYPE_PARAMETERS_IN_OBJECT!><A><!> {
fun test() = 42 <!UNCHECKED_CAST!>as A<!>
}
val b = a.test()
if (a is T) {
<!UNRESOLVED_REFERENCE!>println<!>(a)
}
}
@@ -39,7 +39,7 @@ fun t1(b : Boolean) {
return;
}
doSmth(i)
if (i is Int) {
if (<!USELESS_IS_CHECK!>i is Int<!>) {
return;
}
}
@@ -26,7 +26,7 @@ fun t1(x: Int) = when(x) {
}
fun t5(x: Int) = <!NO_ELSE_IN_WHEN!>when<!> (x) {
is Int -> 1
<!USELESS_IS_CHECK!>is Int<!> -> 1
2 -> 2
}
@@ -13,7 +13,7 @@ fun f2(s: Number?) {
}
fun f3(s: Number?) {
if (s is Int && s as Int == 42);
if (s is Int && s <!USELESS_CAST!>as Int<!> == 42);
checkSubtype<Int>(<!ARGUMENT_TYPE_MISMATCH!>s<!>)
}
@@ -2,7 +2,7 @@
fun foo(o: Any) {
if (o is String) {
val s = o as String
val s = o <!USELESS_CAST!>as String<!>
s.length
}
}
@@ -13,4 +13,4 @@ fun foo1(o: Any) {
val s = o
s.length
}
}
}
@@ -1,7 +1,7 @@
// !CHECK_TYPE
fun foo(x: Number) {
if ((x as Int) is Int) {
if (<!USELESS_IS_CHECK!>(x as Int) is Int<!>) {
checkSubtype<Int>(x)
}
checkSubtype<Int>(x)
@@ -1,11 +1,11 @@
// !CHECK_TYPE
fun noUselessDataFlowInfoCreation(x: Number) {
if (x is Int) { if (x is Int) { if (x is Int) { if (x is Int) { if (x is Int) {
if (x is Int) { if (x is Int) { if (x is Int) { if (x is Int) { if (x is Int) {
if (x is Int) { if (x is Int) { if (x is Int) { if (x is Int) { if (x is Int) {
if (x is Int) { if (x is Int) { if (x is Int) { if (x is Int) { if (x is Int) {
if (x is Int) { if (x is Int) { if (x is Int) { if (x is Int) { if (x is Int) {
if (x is Int) { if (<!USELESS_IS_CHECK!>x is Int<!>) { if (<!USELESS_IS_CHECK!>x is Int<!>) { if (<!USELESS_IS_CHECK!>x is Int<!>) { if (<!USELESS_IS_CHECK!>x is Int<!>) {
if (<!USELESS_IS_CHECK!>x is Int<!>) { if (<!USELESS_IS_CHECK!>x is Int<!>) { if (<!USELESS_IS_CHECK!>x is Int<!>) { if (<!USELESS_IS_CHECK!>x is Int<!>) { if (<!USELESS_IS_CHECK!>x is Int<!>) {
if (<!USELESS_IS_CHECK!>x is Int<!>) { if (<!USELESS_IS_CHECK!>x is Int<!>) { if (<!USELESS_IS_CHECK!>x is Int<!>) { if (<!USELESS_IS_CHECK!>x is Int<!>) { if (<!USELESS_IS_CHECK!>x is Int<!>) {
if (<!USELESS_IS_CHECK!>x is Int<!>) { if (<!USELESS_IS_CHECK!>x is Int<!>) { if (<!USELESS_IS_CHECK!>x is Int<!>) { if (<!USELESS_IS_CHECK!>x is Int<!>) { if (<!USELESS_IS_CHECK!>x is Int<!>) {
if (<!USELESS_IS_CHECK!>x is Int<!>) { if (<!USELESS_IS_CHECK!>x is Int<!>) { if (<!USELESS_IS_CHECK!>x is Int<!>) { if (<!USELESS_IS_CHECK!>x is Int<!>) { if (<!USELESS_IS_CHECK!>x is Int<!>) {
} } } } } } } } } } } } } } } } } } } } } } } } }
}
@@ -5,7 +5,7 @@ enum class En { A, B, С }
fun foo() {
// nullable variable
val en2: Any? = En.A
if (en2 is En) {
if (<!USELESS_IS_CHECK!>en2 is En<!>) {
when (en2) {
En.A -> {}
En.B -> {}
@@ -15,7 +15,7 @@ fun foo() {
// not nullable variable
val en1: Any = En.A
if (en1 is En) {
if (<!USELESS_IS_CHECK!>en1 is En<!>) {
when (en1) {
En.A -> {}
En.B -> {}
@@ -37,4 +37,4 @@ fun bar(x: Any) {
else -> {}
}
}
}
}
@@ -7,7 +7,7 @@ fun <T> foo() = foo() as T
fun <T> foo2(): T = TODO()
val test = foo2().plus("") as String
val test = foo2().plus("") <!USELESS_CAST!>as String<!>
fun <T> T.bar() = this
val barTest = "".bar() as Number
@@ -17,5 +17,5 @@ val asStarList = foo() as List<*>
val safeAs = foo() as? String
val fromIs = foo() is String
val fromNoIs = foo() !is String
val fromIs = <!USELESS_IS_CHECK!>foo() is String<!>
val fromNoIs = <!USELESS_IS_CHECK!>foo() !is String<!>
@@ -1,59 +0,0 @@
// !WITH_NEW_INFERENCE
// !LANGUAGE: +ExpectedTypeFromCast
// !DIAGNOSTICS: -UNUSED_VARIABLE -DEBUG_INFO_LEAKING_THIS
// FILE: a/View.java
package a;
public class View {
}
// FILE: a/Test.java
package a;
public class Test {
public <T extends View> T findViewById(int id);
}
// FILE: 1.kt
package a
class X : View()
class Y<T> : View()
val xExplicit: X = Test().findViewById(0)
val xCast = Test().findViewById(0) as X
val xCastExplicitType = Test().findViewById<X>(0) as X
val xSafeCastExplicitType = Test().findViewById<X>(0) as? X
val yExplicit: Y<String> = Test().findViewById(0)
val yCast = Test().findViewById(0) as Y<String>
class TestChild : Test() {
val xExplicit: X = findViewById(0)
val xCast = findViewById(0) as X
val yExplicit: Y<String> = findViewById(0)
val yCast = findViewById(0) as Y<String>
}
fun test(t: Test) {
val xExplicit: X = t.findViewById(0)
val xCast = t.findViewById(0) as X
val yExplicit: Y<String> = t.findViewById(0)
val yCast = t.findViewById(0) as Y<String>
}
fun test2(t: Test?) {
val xSafeCallSafeCast = t?.findViewById(0) as? X
val xSafeCallSafeCastExplicitType = t?.findViewById<X>(0) as? X
val xSafeCallCast = t?.findViewById(0) as X
val xSafeCallCastExplicitType = t<!UNNECESSARY_SAFE_CALL!>?.<!>findViewById<X>(0) as X
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// !WITH_NEW_INFERENCE
// !LANGUAGE: +ExpectedTypeFromCast
// !DIAGNOSTICS: -UNUSED_VARIABLE -DEBUG_INFO_LEAKING_THIS
@@ -36,7 +36,7 @@ fun f10(init : A?) {
if (!(a is B)) {
return;
}
if (!(a is B)) {
if (!(<!USELESS_IS_CHECK!>a is B<!>)) {
return;
}
}
@@ -58,7 +58,7 @@ fun f11(a : A?) {
is B -> a.bar()
is A -> a.foo()
is Any -> a.foo()
is Any? -> a.<!UNRESOLVED_REFERENCE!>bar<!>()
<!USELESS_IS_CHECK!>is Any?<!> -> a.<!UNRESOLVED_REFERENCE!>bar<!>()
else -> a?.foo()
}
}
@@ -68,12 +68,12 @@ fun f12(a : A?) {
is B -> a.bar()
is A -> a.foo()
is Any -> a.foo();
is Any? -> a.<!UNRESOLVED_REFERENCE!>bar<!>()
<!USELESS_IS_CHECK!>is Any?<!> -> a.<!UNRESOLVED_REFERENCE!>bar<!>()
is C -> a.bar()
else -> a?.foo()
}
if (a is Any?) {
if (<!USELESS_IS_CHECK!>a is Any?<!>) {
a?.<!UNRESOLVED_REFERENCE!>bar<!>()
}
if (a is B) {
@@ -198,7 +198,7 @@ fun mergeSmartCasts(a: Any?) {
when (a) {
is String, is Any -> a.<!UNRESOLVED_REFERENCE!>compareTo<!>("")
}
if (a is String && a is Any) {
if (a is String && <!USELESS_IS_CHECK!>a is Any<!>) {
val i: Int = a.compareTo("")
}
if (a is String && a.compareTo("") == 0) {}
@@ -1,10 +0,0 @@
// !DIAGNOSTICS: -UNUSED_EXPRESSION
inline public fun reg(converter: (Any) -> Any, flag: Boolean) {
flag
converter("")
}
public inline fun register(converter: (Any) -> Any) {
<!USAGE_IS_NOT_INLINABLE!>converter<!> is (Any) -> Any
reg(converter, <!USAGE_IS_NOT_INLINABLE!>converter<!> is (Any) -> Any)
}
+1
View File
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// !DIAGNOSTICS: -UNUSED_EXPRESSION
inline public fun reg(converter: (Any) -> Any, flag: Boolean) {
flag
-11
View File
@@ -1,11 +0,0 @@
// !DIAGNOSTICS: -UNUSED_EXPRESSION
inline public fun reg(converter: (Any) -> Any) {
converter("")
}
public inline fun register(converter: (Any) -> Any) {
reg(when(<!USAGE_IS_NOT_INLINABLE!>converter<!>) {
is (Any) -> Any -> <!USAGE_IS_NOT_INLINABLE!>converter<!>
else -> <!USAGE_IS_NOT_INLINABLE!>converter<!>
})
}
+1
View File
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// !DIAGNOSTICS: -UNUSED_EXPRESSION
inline public fun reg(converter: (Any) -> Any) {
converter("")
@@ -6,7 +6,7 @@ class A
fun <T> test(v: T): T {
val a = if (v !is A) {
foo(v) as T
foo(v) <!USELESS_CAST!>as T<!>
}
else {
v
@@ -18,7 +18,7 @@ fun <T> test(v: T): T {
fun <T> test2(v: T): T {
val a = if (v !is A) {
foo(v) as T
foo(v) <!USELESS_CAST!>as T<!>
}
else {
v as T
@@ -42,7 +42,7 @@ fun <T> test3(v: T): T {
fun <T> test4(v: T): T {
val a: T = if (v !is A) {
foo(v) as T
foo(v) <!USELESS_CAST!>as T<!>
}
else {
v
@@ -1,23 +0,0 @@
sealed class Stmt
class ForStmt : Stmt()
sealed class Expr : Stmt() {
object BinExpr : Expr()
}
fun test(x: Stmt): String =
when (x) {
is Expr -> "expr"
is Stmt -> "stmt"
}
fun test2(x: Stmt): String =
<!NO_ELSE_IN_WHEN!>when<!> (x) {
is Expr -> "expr"
}
fun test3(x: Expr): String =
when (x) {
is Stmt -> "stmt"
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
sealed class Stmt
class ForStmt : Stmt()
@@ -1,15 +0,0 @@
sealed class Sealed {
object First: Sealed()
open class NonFirst: Sealed() {
object Second: NonFirst()
object Third: NonFirst()
}
}
fun foo(s: Sealed): Int {
return <!NO_ELSE_IN_WHEN!>when<!>(s) {
is Sealed.First -> 1
!is Any -> 0
}
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
sealed class Sealed {
object First: Sealed()
open class NonFirst: Sealed() {
@@ -17,7 +17,7 @@ fun String?.gav() {}
fun bar(s: String?) {
if (s != null) return
s.gav()
s as? String
s as String?
s <!USELESS_CAST!>as? String<!>
s <!USELESS_CAST!>as String?<!>
s as String
}
@@ -14,7 +14,7 @@ fun g(a: SomeClass?) {
a.hashCode()
a.foo
(a as? SomeSubClass)<!UNSAFE_CALL!>.<!>foo
(a as SomeSubClass).foo
(a <!USELESS_CAST!>as SomeSubClass<!>).foo
}
val b = (a as? SomeSubClass)?.foo
if (b != null) {
@@ -22,7 +22,7 @@ fun g(a: SomeClass?) {
a.hashCode()
a.foo
(a as? SomeSubClass)<!UNSAFE_CALL!>.<!>foo
(a as SomeSubClass).foo
(a <!USELESS_CAST!>as SomeSubClass<!>).foo
}
val c = a as? SomeSubClass
if (c != null) {
@@ -33,4 +33,4 @@ fun g(a: SomeClass?) {
c.hashCode()
c.foo
}
}
}
@@ -14,7 +14,7 @@ fun g(a: SomeClass?) {
a.hashCode()
a.foo
(a as? SomeSubClass)<!UNSAFE_CALL!>.<!>foo
(a as SomeSubClass).foo
(a <!USELESS_CAST!>as SomeSubClass<!>).foo
}
val b = (a as? SomeSubClass)?.foo
if (b != null) {
@@ -22,7 +22,7 @@ fun g(a: SomeClass?) {
a.hashCode()
a.foo
(a as? SomeSubClass)<!UNSAFE_CALL!>.<!>foo
(a as SomeSubClass).foo
(a <!USELESS_CAST!>as SomeSubClass<!>).foo
}
val c = a as? SomeSubClass
if (c != null) {
@@ -33,4 +33,4 @@ fun g(a: SomeClass?) {
c.hashCode()
c.foo
}
}
}
@@ -1,25 +0,0 @@
// !LANGUAGE: +SafeCastCheckBoundSmartCasts
// See KT-20752
class Unstable {
val first: String? get() = null
}
class StringList {
fun remove(s: String) = s
}
fun StringList.remove(s: String?) = s ?: ""
fun foo(list: StringList, arg: Unstable) {
list.remove(arg.first)
if (arg.first as? String != null) {
// Should be still resolved to extension, without smart cast or smart cast impossible
list.remove(arg.first)
}
val s = arg.first as? String
if (s != null) {
// Should be still resolved to extension, without smart cast or smart cast impossible
list.remove(arg.first)
}
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// !LANGUAGE: +SafeCastCheckBoundSmartCasts
// See KT-20752
@@ -7,7 +7,7 @@ fun <T> T?.let(f: (T) -> Unit) {
}
fun test(your: Your?) {
(your?.foo() as? Any)?.let {}
(your?.foo() <!USELESS_CAST!>as? Any<!>)?.let {}
// strange smart cast to 'Your' at this point
your<!UNSAFE_CALL!>.<!>hashCode()
}
}
@@ -1,15 +0,0 @@
// Type inference failed after smart cast
interface A<T>
interface B<T> : A<T>
fun <T> foo(b: A<T>) = b
fun <T> test(a: A<T>) {
if (a is Any) {
// Error:(9, 9) Kotlin: Type inference failed: fun <T> foo(b: A<T>): kotlin.Unit
// cannot be applied to (A<T>)
foo(a)
}
foo(a) // ok
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// Type inference failed after smart cast
interface A<T>
@@ -19,10 +19,10 @@ fun foo(a: A) {
fun foo2(a: A) {
if (a is C) {
if (a is B) {
if (<!USELESS_IS_CHECK!>a is B<!>) {
val t = when (a) {
is CC -> "CC"
}
}
}
}
}
@@ -12,7 +12,7 @@ object DD : D()
fun foo1(a: A) {
if (a is B) {
if (a is D) {
if (a is C) {
if (<!USELESS_IS_CHECK!>a is C<!>) {
val t =
when (a) {
is DD -> "DD"
@@ -25,7 +25,7 @@ fun foo1(a: A) {
fun foo2(a: A) {
if (a is B) {
if (a is D) {
if (a is C) {
if (<!USELESS_IS_CHECK!>a is C<!>) {
val t =
when (a) {
is DD -> "DD"
@@ -33,4 +33,4 @@ fun foo2(a: A) {
}
}
}
}
}
@@ -1,28 +0,0 @@
//KT-5455 Need warning about redundant type cast
fun foo(o: Any): Int {
if (o is String) {
return (o as String).length
}
return -1
}
open class A {
fun foo() {}
}
class B: A()
fun test(a: Any?) {
if (a is B) {
(a as A).foo()
}
}
fun test1(a: B) {
(a as A?)?.foo()
}
fun test2(b: B?) {
if (b != null) {
(b as A).foo()
}
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
//KT-5455 Need warning about redundant type cast
fun foo(o: Any): Int {
if (o is String) {
@@ -1,13 +1,13 @@
// See also KT-10992: we should have no errors for all unsafe hashCode() calls
fun foo(arg: Any?) {
val x = arg as? Any ?: return
val x = arg <!USELESS_CAST!>as? Any<!> ?: return
arg.hashCode()
x.hashCode()
}
fun bar(arg: Any?) {
arg as? Any ?: return
arg <!USELESS_CAST!>as? Any<!> ?: return
arg.hashCode()
}
@@ -1,4 +0,0 @@
@Suppress("REDUNDANT_NULLABLE")
class C {
fun foo(): String?? = null as Nothing??
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
@Suppress("REDUNDANT_NULLABLE")
class C {
fun foo(): String?? = null <!USELESS_CAST!>as Nothing??<!>
@@ -1,6 +0,0 @@
class C {
@Suppress("REDUNDANT_NULLABLE")
companion object {
val foo: String?? = null as Nothing??
}
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
class C {
@Suppress("REDUNDANT_NULLABLE")
companion object {
@@ -1,4 +0,0 @@
fun foo(): Any? {
@Suppress("REDUNDANT_NULLABLE")
return null as Nothing??
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
fun foo(): Any? {
@Suppress("REDUNDANT_NULLABLE")
return null <!USELESS_CAST!>as Nothing??<!>
@@ -1,4 +0,0 @@
class C {
@Suppress("REDUNDANT_NULLABLE")
fun foo(): String?? = null as Nothing??
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
class C {
@Suppress("REDUNDANT_NULLABLE")
fun foo(): String?? = null <!USELESS_CAST!>as Nothing??<!>
@@ -1,7 +0,0 @@
class C {
fun foo(): Any? {
@Suppress("REDUNDANT_NULLABLE")
val v: String?? = null as Nothing??
return v
}
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
class C {
fun foo(): Any? {
@Suppress("REDUNDANT_NULLABLE")
@@ -1,4 +0,0 @@
@Suppress("REDUNDANT_NULLABLE")
object C {
fun foo(): String?? = null as Nothing??
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
@Suppress("REDUNDANT_NULLABLE")
object C {
fun foo(): String?? = null <!USELESS_CAST!>as Nothing??<!>
@@ -1,3 +0,0 @@
class C {
fun foo(@Suppress("REDUNDANT_NULLABLE") p: String?? = null as Nothing??) = p
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
class C {
fun foo(@Suppress("REDUNDANT_NULLABLE") p: String?? = null <!USELESS_CAST!>as Nothing??<!>) = p
}
@@ -1,4 +0,0 @@
class C {
@Suppress("REDUNDANT_NULLABLE")
val foo: String?? = null as Nothing?
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
class C {
@Suppress("REDUNDANT_NULLABLE")
val foo: String?? = null <!USELESS_CAST!>as Nothing?<!>
@@ -1,5 +0,0 @@
class C {
val foo: String?
@Suppress("REDUNDANT_NULLABLE")
get(): String?? = null as Nothing??
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
class C {
val foo: String?
@Suppress("REDUNDANT_NULLABLE")
+3 -3
View File
@@ -20,9 +20,9 @@ fun foo() : Int {
val x = 1
when (x) {
is String -> 1
!is Int -> 1
is Any? -> 1
is Any -> 1
<!USELESS_IS_CHECK!>!is Int<!> -> 1
<!USELESS_IS_CHECK!>is Any?<!> -> 1
<!USELESS_IS_CHECK!>is Any<!> -> 1
s -> 1
1 -> 1
1 <!OVERLOAD_RESOLUTION_AMBIGUITY!>+<!> <!UNRESOLVED_REFERENCE!>a<!> -> 1
@@ -23,7 +23,7 @@ fun foo(s: Any): String {
fun bar(s: Any): String {
val x = when (s) {
is String -> s as String // meaningless
is String -> s <!USELESS_CAST!>as String<!> // meaningless
is Int -> "$s"
else -> return ""
}
@@ -1,5 +1,5 @@
fun f(a: Array<out Number>) = a.isArrayOf<Int>()
fun f1(a: Array<out Number>) = a is Array<*>
fun f1(a: Array<out Number>) = <!USELESS_IS_CHECK!>a is Array<*><!>
fun f2(a: Array<out Number>) = a is Array<Int>
fun f2(a: Array<out Number>) = a is Array<Int>
@@ -95,7 +95,7 @@ fun branchedAndNestedWithNativeOperators(x: Any?, y: Any?) {
equalsTrue(isInt(y) && isString(y)) // y is Int, String
)
&&
(1 == 2 || y is Int || isString(y))
(1 == 2 || <!USELESS_IS_CHECK!>y is Int<!> || isString(y))
)
x.length
y.length
@@ -1,11 +0,0 @@
// !LANGUAGE: +AllowContractsForCustomFunctions +UseReturnsEffect
// !USE_EXPERIMENTAL: kotlin.contracts.ExperimentalContracts
// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER
import kotlin.contracts.*
fun f3(value: String?) {
if (!value.isNullOrEmpty() is Boolean) {
value<!UNSAFE_CALL!>.<!>length
}
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// !LANGUAGE: +AllowContractsForCustomFunctions +UseReturnsEffect
// !USE_EXPERIMENTAL: kotlin.contracts.ExperimentalContracts
// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER