[FIR] Implement checker for exhaustive when's in expression position
This commit is contained in:
@@ -72,7 +72,7 @@ fun main1() {
|
||||
|
||||
1."sdf"
|
||||
1.{}
|
||||
1.if (true) {}
|
||||
1.<!INVALID_IF_AS_EXPRESSION!>if<!> (true) {}
|
||||
}
|
||||
|
||||
fun test() {
|
||||
|
||||
@@ -70,7 +70,7 @@ fun blockReturnValueTypeMatch1() : Int {
|
||||
return if (1 > 2) 1.0 else 2.0
|
||||
}
|
||||
fun blockReturnValueTypeMatch2() : Int {
|
||||
return if (1 > 2) 1
|
||||
return <!INVALID_IF_AS_EXPRESSION!>if<!> (1 > 2) 1
|
||||
}
|
||||
fun blockReturnValueTypeMatch3() : Int {
|
||||
return if (1 > 2) else 1
|
||||
@@ -106,7 +106,7 @@ fun blockReturnValueTypeMatch9() : Int {
|
||||
1.0
|
||||
}
|
||||
fun blockReturnValueTypeMatch10() : Int {
|
||||
return if (1 > 2)
|
||||
return <!INVALID_IF_AS_EXPRESSION!>if<!> (1 > 2)
|
||||
1
|
||||
}
|
||||
fun blockReturnValueTypeMatch11() : Int {
|
||||
|
||||
@@ -29,7 +29,7 @@ fun foo(d: Direction) = when(d) { //no 'else' should be requested
|
||||
Direction.EAST -> 4
|
||||
}
|
||||
|
||||
fun foo1(d: Direction) = when(d) {
|
||||
fun foo1(d: Direction) = <!NO_ELSE_IN_WHEN!>when<!>(d) {
|
||||
Direction.NORTH -> 1
|
||||
Direction.SOUTH -> 2
|
||||
Direction.WEST -> 3
|
||||
@@ -41,7 +41,7 @@ fun bar(c: Color) = when (c) {
|
||||
Color.BLUE -> 3
|
||||
}
|
||||
|
||||
fun bar1(c: Color) = when (c) {
|
||||
fun bar1(c: Color) = <!NO_ELSE_IN_WHEN!>when<!> (c) {
|
||||
Color.RED -> 1
|
||||
Color.GREEN -> 2
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
fun foo(x: Unit) = x
|
||||
|
||||
fun test() {
|
||||
if (false);
|
||||
if (true);
|
||||
|
||||
val x = if (false);
|
||||
foo(x)
|
||||
|
||||
val y: Unit = if (false);
|
||||
foo(y)
|
||||
|
||||
foo({if (1==1);}())
|
||||
|
||||
return if (true);
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
fun foo(x: Unit) = x
|
||||
|
||||
fun test() {
|
||||
|
||||
+2
-2
@@ -11,7 +11,7 @@ fun testMixedIfAndWhen() =
|
||||
else 1
|
||||
true -> if (true) 42
|
||||
else println()
|
||||
else -> if (true) println()
|
||||
else -> <!INVALID_IF_AS_EXPRESSION!>if<!> (true) println()
|
||||
}
|
||||
else println()
|
||||
|
||||
@@ -28,4 +28,4 @@ fun testWrappedExpressions() =
|
||||
}
|
||||
else {
|
||||
(((((42)) + 1)))
|
||||
}
|
||||
}
|
||||
|
||||
+29
-29
@@ -11,21 +11,21 @@ val mlist = MList()
|
||||
|
||||
fun work() {}
|
||||
|
||||
val xx1 = if (true) 42
|
||||
val xx2: Unit = if (true) 42
|
||||
val xx3 = idAny(if (true) 42)
|
||||
val xx4 = id(if (true) 42)
|
||||
val xx5 = idUnit(if (true) 42)
|
||||
val xx6 = null ?: if (true) 42
|
||||
val xx7 = "" + if (true) 42
|
||||
val xx1 = <!INVALID_IF_AS_EXPRESSION!>if<!> (true) 42
|
||||
val xx2: Unit = <!INVALID_IF_AS_EXPRESSION!>if<!> (true) 42
|
||||
val xx3 = idAny(<!INVALID_IF_AS_EXPRESSION!>if<!> (true) 42)
|
||||
val xx4 = id(<!INVALID_IF_AS_EXPRESSION!>if<!> (true) 42)
|
||||
val xx5 = idUnit(<!INVALID_IF_AS_EXPRESSION!>if<!> (true) 42)
|
||||
val xx6 = null ?: <!INVALID_IF_AS_EXPRESSION!>if<!> (true) 42
|
||||
val xx7 = "" + <!INVALID_IF_AS_EXPRESSION!>if<!> (true) 42
|
||||
|
||||
val wxx1 = when { true -> 42 }
|
||||
val wxx2: Unit = when { true -> 42 }
|
||||
val wxx3 = idAny(when { true -> 42 })
|
||||
val wxx4 = id(when { true -> 42 })
|
||||
val wxx5 = idUnit(when { true -> 42 })
|
||||
val wxx6 = null ?: when { true -> 42 }
|
||||
val wxx7 = "" + when { true -> 42 }
|
||||
val wxx1 = <!NO_ELSE_IN_WHEN!>when<!> { true -> 42 }
|
||||
val wxx2: Unit = <!NO_ELSE_IN_WHEN!>when<!> { true -> 42 }
|
||||
val wxx3 = idAny(<!NO_ELSE_IN_WHEN!>when<!> { true -> 42 })
|
||||
val wxx4 = id(<!NO_ELSE_IN_WHEN!>when<!> { true -> 42 })
|
||||
val wxx5 = idUnit(<!NO_ELSE_IN_WHEN!>when<!> { true -> 42 })
|
||||
val wxx6 = null ?: <!NO_ELSE_IN_WHEN!>when<!> { true -> 42 }
|
||||
val wxx7 = "" + <!NO_ELSE_IN_WHEN!>when<!> { true -> 42 }
|
||||
|
||||
val fn1 = { if (true) 42 }
|
||||
val fn2 = { if (true) mlist.add() }
|
||||
@@ -41,24 +41,24 @@ val ufn4: () -> Unit = { when { true -> 42 } }
|
||||
val ufn5: () -> Unit = { when { true -> mlist.add() } }
|
||||
val ufn6: () -> Unit = { when { true -> work() } }
|
||||
|
||||
fun f1() = if (true) work()
|
||||
fun f2() = if (true) mlist.add()
|
||||
fun f3() = if (true) 42
|
||||
fun f4(): Unit = if (true) work()
|
||||
fun f5(): Unit = if (true) mlist.add()
|
||||
fun f6(): Unit = if (true) 42
|
||||
fun g1() = when { true -> work() }
|
||||
fun g2() = when { true -> mlist.add() }
|
||||
fun g3() = when { true -> 42 }
|
||||
fun g4(): Unit = when { true -> work() }
|
||||
fun g5(): Unit = when { true -> mlist.add() }
|
||||
fun g6(): Unit = when { true -> 42 }
|
||||
fun f1() = <!INVALID_IF_AS_EXPRESSION!>if<!> (true) work()
|
||||
fun f2() = <!INVALID_IF_AS_EXPRESSION!>if<!> (true) mlist.add()
|
||||
fun f3() = <!INVALID_IF_AS_EXPRESSION!>if<!> (true) 42
|
||||
fun f4(): Unit = <!INVALID_IF_AS_EXPRESSION!>if<!> (true) work()
|
||||
fun f5(): Unit = <!INVALID_IF_AS_EXPRESSION!>if<!> (true) mlist.add()
|
||||
fun f6(): Unit = <!INVALID_IF_AS_EXPRESSION!>if<!> (true) 42
|
||||
fun g1() = <!NO_ELSE_IN_WHEN!>when<!> { true -> work() }
|
||||
fun g2() = <!NO_ELSE_IN_WHEN!>when<!> { true -> mlist.add() }
|
||||
fun g3() = <!NO_ELSE_IN_WHEN!>when<!> { true -> 42 }
|
||||
fun g4(): Unit = <!NO_ELSE_IN_WHEN!>when<!> { true -> work() }
|
||||
fun g5(): Unit = <!NO_ELSE_IN_WHEN!>when<!> { true -> mlist.add() }
|
||||
fun g6(): Unit = <!NO_ELSE_IN_WHEN!>when<!> { true -> 42 }
|
||||
|
||||
fun foo1(x: String?) {
|
||||
"" + if (true) 42
|
||||
"" + <!INVALID_IF_AS_EXPRESSION!>if<!> (true) 42
|
||||
w@while (true) {
|
||||
x ?: if (true) break
|
||||
x ?: when { true -> break@w }
|
||||
x ?: <!INVALID_IF_AS_EXPRESSION!>if<!> (true) break
|
||||
x ?: <!NO_ELSE_IN_WHEN!>when<!> { true -> break@w }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -4,7 +4,7 @@
|
||||
fun example() {
|
||||
val a = if (true) true else false
|
||||
val b = if (true) else false
|
||||
val c = if (true) true
|
||||
val c = <!INVALID_IF_AS_EXPRESSION!>if<!> (true) true
|
||||
val d = if (true) true else;
|
||||
val e = if (true) {} else false
|
||||
val f = if (true) true else {}
|
||||
@@ -27,7 +27,7 @@ fun example() {
|
||||
}()
|
||||
|
||||
fun t(): Boolean {
|
||||
return if (true) true
|
||||
return <!INVALID_IF_AS_EXPRESSION!>if<!> (true) true
|
||||
}
|
||||
|
||||
return if (true) true else {}
|
||||
|
||||
Vendored
+2
-2
@@ -99,10 +99,10 @@ fun testImplicitCoercion() {
|
||||
else -> z--
|
||||
}
|
||||
|
||||
var iff = if (true) {
|
||||
var iff = <!INVALID_IF_AS_EXPRESSION!>if<!> (true) {
|
||||
z = 34
|
||||
}
|
||||
val g = if (true) 4
|
||||
val g = <!INVALID_IF_AS_EXPRESSION!>if<!> (true) 4
|
||||
val h = if (false) 4 else {}
|
||||
|
||||
<!INAPPLICABLE_CANDIDATE!>bar<!>(if (true) {
|
||||
|
||||
+1
-1
@@ -25,7 +25,7 @@ fun t1(x: Int) = when(x) {
|
||||
else -> 1
|
||||
}
|
||||
|
||||
fun t5(x: Int) = when (x) {
|
||||
fun t5(x: Int) = <!NO_ELSE_IN_WHEN!>when<!> (x) {
|
||||
is Int -> 1
|
||||
2 -> 2
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ fun f3(s: Number?) {
|
||||
}
|
||||
|
||||
fun f4(s: Int?) {
|
||||
var u = if (s!! == 42);
|
||||
if (u == Unit) u = if (s == 239);
|
||||
var u = <!INVALID_IF_AS_EXPRESSION!>if<!> (s!! == 42);
|
||||
if (u == Unit) u = <!INVALID_IF_AS_EXPRESSION!>if<!> (s == 239);
|
||||
return u
|
||||
}
|
||||
}
|
||||
|
||||
@@ -142,7 +142,7 @@ fun getStringLength(obj : Any) : Char? {
|
||||
}
|
||||
|
||||
fun toInt(i: Int?): Int = if (i != null) i else 0
|
||||
fun illegalWhenBody(a: Any): Int = when(a) {
|
||||
fun illegalWhenBody(a: Any): Int = <!NO_ELSE_IN_WHEN!>when<!>(a) {
|
||||
is Int -> a
|
||||
is String -> a
|
||||
}
|
||||
|
||||
@@ -13,11 +13,11 @@ fun test(x: Stmt): String =
|
||||
}
|
||||
|
||||
fun test2(x: Stmt): String =
|
||||
when (x) {
|
||||
<!NO_ELSE_IN_WHEN!>when<!> (x) {
|
||||
is Expr -> "expr"
|
||||
}
|
||||
|
||||
fun test3(x: Expr): String =
|
||||
when (x) {
|
||||
<!NO_ELSE_IN_WHEN!>when<!> (x) {
|
||||
is Stmt -> "stmt"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ sealed class Base {
|
||||
// No else required
|
||||
}
|
||||
|
||||
fun bar() = when (this) {
|
||||
fun bar() = <!NO_ELSE_IN_WHEN!>when<!> (this) {
|
||||
is A -> 1
|
||||
is B.B1 -> 2
|
||||
}
|
||||
@@ -31,4 +31,4 @@ sealed class Base {
|
||||
A.A1 -> 2
|
||||
is A.A2 -> 3
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
sealed class A
|
||||
sealed class B : A()
|
||||
|
||||
class C : B()
|
||||
class D : B()
|
||||
|
||||
fun test(a: A): Any {
|
||||
return when (a) {
|
||||
is C -> ""
|
||||
is D -> ""
|
||||
}
|
||||
}
|
||||
|
||||
fun test2(a: A): Any {
|
||||
return when (a) {
|
||||
is B -> ""
|
||||
}
|
||||
}
|
||||
|
||||
fun test3(a: A): Any {
|
||||
return when (a) {
|
||||
is D -> ""
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
sealed class A
|
||||
sealed class B : A()
|
||||
|
||||
|
||||
-47
@@ -1,47 +0,0 @@
|
||||
sealed class Sealed() {
|
||||
object First: Sealed()
|
||||
open class NonFirst: Sealed() {
|
||||
class NonSecond: NonFirst() {
|
||||
object Third: Sealed()
|
||||
class NonThird: Sealed() {
|
||||
object Fourth: NonFirst()
|
||||
class Fifth: Sealed()
|
||||
}
|
||||
}
|
||||
object Second: Sealed()
|
||||
}
|
||||
}
|
||||
|
||||
fun foo(s: Sealed) = when(s) {
|
||||
Sealed.First -> 1
|
||||
is Sealed.NonFirst -> 2
|
||||
Sealed.NonFirst.Second -> 4
|
||||
Sealed.NonFirst.NonSecond.Third -> 6
|
||||
is Sealed.NonFirst.NonSecond.NonThird -> 8
|
||||
is Sealed.NonFirst.NonSecond.NonThird.Fifth -> 10
|
||||
// no else required
|
||||
}
|
||||
|
||||
fun fooWithElse(s: Sealed) = when(s) {
|
||||
Sealed.First -> 1
|
||||
Sealed.NonFirst.NonSecond.Third -> 6
|
||||
is Sealed.NonFirst.NonSecond.NonThird.Fifth -> 10
|
||||
else -> 0
|
||||
}
|
||||
|
||||
fun fooWithoutElse(s: Sealed) = when(s) {
|
||||
Sealed.First -> 1
|
||||
is Sealed.NonFirst -> 2
|
||||
Sealed.NonFirst.NonSecond.Third -> 6
|
||||
is Sealed.NonFirst.NonSecond.NonThird -> 8
|
||||
is Sealed.NonFirst.NonSecond.NonThird.Fifth -> 10
|
||||
}
|
||||
|
||||
fun barWithoutElse(s: Sealed) = when(s) {
|
||||
Sealed.First -> 1
|
||||
is Sealed.NonFirst -> 2
|
||||
Sealed.NonFirst.Second -> 4
|
||||
is Sealed.NonFirst.NonSecond.NonThird -> 8
|
||||
is Sealed.NonFirst.NonSecond.NonThird.Fifth -> 10
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
sealed class Sealed() {
|
||||
object First: Sealed()
|
||||
open class NonFirst: Sealed() {
|
||||
|
||||
@@ -1,64 +0,0 @@
|
||||
// ISSUE: KT-13495
|
||||
// !DIAGNOSTICS: -UNUSED_VARIABLE
|
||||
// !LANGUAGE: +AllowSealedInheritorsInDifferentFilesOfSamePackage
|
||||
|
||||
// FILE: Base.kt
|
||||
|
||||
sealed class Base {
|
||||
class A : Base()
|
||||
}
|
||||
|
||||
// FILE: B.kt
|
||||
|
||||
class B : Base()
|
||||
|
||||
// FILE: Container.kt
|
||||
|
||||
class Containter {
|
||||
class C : Base()
|
||||
|
||||
inner class D : Base()
|
||||
}
|
||||
|
||||
// FILE: main.kt
|
||||
|
||||
fun test_OK(base: Base) {
|
||||
val x = when (base) {
|
||||
is Base.A -> 1
|
||||
is B -> 2
|
||||
is Containter.C -> 3
|
||||
is Containter.D -> 4
|
||||
}
|
||||
}
|
||||
|
||||
fun test_error_1(base: Base) {
|
||||
val x = when (base) {
|
||||
is B -> 2
|
||||
is Containter.C -> 3
|
||||
is Containter.D -> 4
|
||||
}
|
||||
}
|
||||
|
||||
fun test_error_2(base: Base) {
|
||||
val x = when (base) {
|
||||
is Base.A -> 1
|
||||
is Containter.C -> 3
|
||||
is Containter.D -> 4
|
||||
}
|
||||
}
|
||||
|
||||
fun test_error_3(base: Base) {
|
||||
val x = when (base) {
|
||||
is Base.A -> 1
|
||||
is B -> 2
|
||||
is Containter.D -> 4
|
||||
}
|
||||
}
|
||||
|
||||
fun test_error_4(base: Base) {
|
||||
val x = when (base) {
|
||||
is Base.A -> 1
|
||||
is B -> 2
|
||||
is Containter.C -> 3
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// ISSUE: KT-13495
|
||||
// !DIAGNOSTICS: -UNUSED_VARIABLE
|
||||
// !LANGUAGE: +AllowSealedInheritorsInDifferentFilesOfSamePackage
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
sealed class Sealed(val x: Int) {
|
||||
object First: Sealed(12)
|
||||
open class NonFirst(x: Int, val y: Int): Sealed(x) {
|
||||
object Second: NonFirst(34, 2)
|
||||
object Third: NonFirst(56, 3)
|
||||
}
|
||||
}
|
||||
|
||||
fun foo(s: Sealed): Int {
|
||||
return when(s) {
|
||||
is Sealed.NonFirst -> 0
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
sealed class Sealed(val x: Int) {
|
||||
object First: Sealed(12)
|
||||
open class NonFirst(x: Int, val y: Int): Sealed(x) {
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
sealed class Sealed(val x: Int) {
|
||||
object First: Sealed(12)
|
||||
open class NonFirst(x: Int, val y: Int): Sealed(x) {
|
||||
object Second: NonFirst(34, 2)
|
||||
object Third: NonFirst(56, 3)
|
||||
}
|
||||
}
|
||||
|
||||
fun foo(s: Sealed): Int {
|
||||
return when(s) {
|
||||
!is Sealed.NonFirst -> 1
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
sealed class Sealed(val x: Int) {
|
||||
object First: Sealed(12)
|
||||
open class NonFirst(x: Int, val y: Int): Sealed(x) {
|
||||
|
||||
-22
@@ -1,22 +0,0 @@
|
||||
sealed class Sealed(val x: Int) {
|
||||
interface ITuple {
|
||||
val x: Int
|
||||
val y: Int
|
||||
}
|
||||
class Tuple(override val x: Int, override val y: Int): ITuple
|
||||
object First: Sealed(12)
|
||||
open class NonFirst(tuple: Tuple): Sealed(tuple.x), ITuple {
|
||||
override val y: Int = tuple.y
|
||||
object Second: NonFirst(Tuple(34, 2))
|
||||
class Third: NonFirst(Tuple(56, 3))
|
||||
}
|
||||
}
|
||||
|
||||
fun foo(s: Sealed): Int {
|
||||
return when(s) {
|
||||
is Sealed.First -> 1
|
||||
!is Sealed.ITuple -> 0
|
||||
// else required
|
||||
}
|
||||
}
|
||||
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
sealed class Sealed(val x: Int) {
|
||||
interface ITuple {
|
||||
val x: Int
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@ sealed class Sealed {
|
||||
}
|
||||
|
||||
fun foo(s: Sealed): Int {
|
||||
return when(s) {
|
||||
return <!NO_ELSE_IN_WHEN!>when<!>(s) {
|
||||
is Sealed.First -> 1
|
||||
!is Any -> 0
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ sealed class Tree {
|
||||
is Node -> this.left.max()
|
||||
}
|
||||
|
||||
fun maxIsClass(): Int = when(this) {
|
||||
fun maxIsClass(): Int = <!NO_ELSE_IN_WHEN!>when<!>(this) {
|
||||
Empty -> -1
|
||||
Leaf -> 0
|
||||
is Node -> this.left.max()
|
||||
@@ -20,4 +20,4 @@ sealed class Tree {
|
||||
is Node -> this.left.max()
|
||||
else -> -1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
// !DIAGNOSTICS: -UNUSED_EXPRESSION
|
||||
sealed class Sealed {
|
||||
|
||||
}
|
||||
|
||||
fun foo(s: Sealed): Int {
|
||||
return when(s) {
|
||||
// We do not return anything, so else branch must be here
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// !DIAGNOSTICS: -UNUSED_EXPRESSION
|
||||
sealed class Sealed {
|
||||
|
||||
|
||||
+3
-3
@@ -10,7 +10,7 @@ object CC : C()
|
||||
fun foo(a: A) {
|
||||
if (a is B) {
|
||||
if (a is C) {
|
||||
val t = when (a) {
|
||||
val t = <!NO_ELSE_IN_WHEN!>when<!> (a) {
|
||||
is CC -> "CC"
|
||||
}
|
||||
}
|
||||
@@ -20,9 +20,9 @@ fun foo(a: A) {
|
||||
fun foo2(a: A) {
|
||||
if (a is C) {
|
||||
if (a is B) {
|
||||
val t = when (a) {
|
||||
val t = <!NO_ELSE_IN_WHEN!>when<!> (a) {
|
||||
is CC -> "CC"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
public fun foo(x: String?, y: String?): Int {
|
||||
while (true) {
|
||||
x ?: <!INVALID_IF_AS_EXPRESSION!>if<!> (y == null) break
|
||||
// y is nullable if x != null
|
||||
y<!UNSAFE_CALL!>.<!>length
|
||||
}
|
||||
// y is null because of the break
|
||||
return y<!UNSAFE_CALL!>.<!>length
|
||||
}
|
||||
+1
-2
@@ -1,4 +1,3 @@
|
||||
// FIR_IDENTICAL
|
||||
public fun foo(x: String?, y: String?): Int {
|
||||
while (true) {
|
||||
x ?: if (y == null) break
|
||||
@@ -7,4 +6,4 @@ public fun foo(x: String?, y: String?): Int {
|
||||
}
|
||||
// y is null because of the break
|
||||
return y<!UNSAFE_CALL!>.<!>length
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
fun foo() {}
|
||||
|
||||
val x: Unit? = when ("A") {
|
||||
"B" -> foo()
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
fun foo() {}
|
||||
|
||||
val x: Unit? = <!NO_ELSE_IN_WHEN!>when<!> ("A") {
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
enum class E { A, B }
|
||||
|
||||
fun test(e: E?) = when (e) {
|
||||
fun test(e: E?) = <!NO_ELSE_IN_WHEN!>when<!> (e) {
|
||||
E.A -> 1
|
||||
E.B -> 2
|
||||
}
|
||||
|
||||
+9
-9
@@ -1,18 +1,18 @@
|
||||
/*
|
||||
* KOTLIN DIAGNOSTICS SPEC TEST (POSITIVE)
|
||||
* KOTLIN DIAGNOSTICS SPEC TEST (NEGATIVE)
|
||||
*
|
||||
* SPEC VERSION: 0.1-152
|
||||
* SPEC VERSION: 0.1-313
|
||||
* PRIMARY LINKS: expressions, when-expression -> paragraph 5 -> sentence 1
|
||||
* expressions, when-expression, exhaustive-when-expressions -> paragraph 1 -> sentence 1
|
||||
* expressions, when-expression, exhaustive-when-expressions -> paragraph 2 -> sentence 3
|
||||
* expressions, when-expression, exhaustive-when-expressions -> paragraph 2 -> sentence 10
|
||||
* expressions, when-expression, exhaustive-when-expressions -> paragraph 2 -> sentence 4
|
||||
* expressions, when-expression, exhaustive-when-expressions -> paragraph 2 -> sentence 5
|
||||
*/
|
||||
|
||||
// See also: KT-3743
|
||||
fun foo(arg: Boolean?): String {
|
||||
// Must be NOT exhaustive
|
||||
return when(arg) {
|
||||
true -> "truth"
|
||||
false -> "falsehood"
|
||||
fun foo(arg: Boolean): String {
|
||||
// Must be exhaustive
|
||||
return <!NO_ELSE_IN_WHEN!>when<!>(arg) {
|
||||
2 == 2 -> "truth"
|
||||
2 == 1 -> "falsehood"
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,3 @@
|
||||
// FIR_IDENTICAL
|
||||
/*
|
||||
* KOTLIN DIAGNOSTICS SPEC TEST (NEGATIVE)
|
||||
*
|
||||
|
||||
@@ -12,7 +12,7 @@ enum class MyEnum {
|
||||
}
|
||||
|
||||
fun foo(x: MyEnum): Int {
|
||||
return when (x) {
|
||||
return <!NO_ELSE_IN_WHEN!>when<!> (x) {
|
||||
is <!UNRESOLVED_REFERENCE!>MyEnum.A<!> -> 1
|
||||
is <!UNRESOLVED_REFERENCE!>MyEnum.B<!> -> 2
|
||||
is <!UNRESOLVED_REFERENCE!>MyEnum.C<!> -> 3
|
||||
|
||||
@@ -13,7 +13,7 @@ enum class MyEnum {
|
||||
}
|
||||
|
||||
fun foo(x: MyEnum): Int {
|
||||
return when (x) {
|
||||
return <!NO_ELSE_IN_WHEN!>when<!> (x) {
|
||||
MyEnum.A -> 1
|
||||
is <!UNRESOLVED_REFERENCE!>MyEnum.B<!> -> 2
|
||||
is <!UNRESOLVED_REFERENCE!>MyEnum.C<!> -> 3
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
/*
|
||||
* KOTLIN DIAGNOSTICS SPEC TEST (NEGATIVE)
|
||||
*
|
||||
* SPEC VERSION: 0.1-152
|
||||
* PRIMARY LINKS: expressions, when-expression -> paragraph 5 -> sentence 1
|
||||
* expressions, when-expression -> paragraph 9 -> sentence 2
|
||||
* expressions, when-expression, exhaustive-when-expressions -> paragraph 1 -> sentence 1
|
||||
*/
|
||||
|
||||
fun foo(x: Int) {
|
||||
val y: Unit = when (x) {
|
||||
2 -> {}
|
||||
3 -> {}
|
||||
}
|
||||
return y
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
/*
|
||||
* KOTLIN DIAGNOSTICS SPEC TEST (NEGATIVE)
|
||||
*
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
/*
|
||||
* KOTLIN DIAGNOSTICS SPEC TEST (NEGATIVE)
|
||||
*
|
||||
* SPEC VERSION: 0.1-152
|
||||
* PRIMARY LINKS: expressions, when-expression -> paragraph 5 -> sentence 1
|
||||
* expressions, when-expression -> paragraph 9 -> sentence 2
|
||||
* expressions, when-expression, exhaustive-when-expressions -> paragraph 1 -> sentence 1
|
||||
*/
|
||||
|
||||
fun foo(x: Int): Any {
|
||||
val v = when (x) {
|
||||
2 -> 0
|
||||
}
|
||||
return v
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
/*
|
||||
* KOTLIN DIAGNOSTICS SPEC TEST (NEGATIVE)
|
||||
*
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
/*
|
||||
* KOTLIN DIAGNOSTICS SPEC TEST (NEGATIVE)
|
||||
*
|
||||
* SPEC VERSION: 0.1-152
|
||||
* PRIMARY LINKS: expressions, when-expression -> paragraph 5 -> sentence 1
|
||||
* expressions, when-expression -> paragraph 9 -> sentence 2
|
||||
* expressions, when-expression, exhaustive-when-expressions -> paragraph 1 -> sentence 1
|
||||
*/
|
||||
|
||||
fun foo(x: Int): Any {
|
||||
return when (x) {
|
||||
2 -> 0
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
/*
|
||||
* KOTLIN DIAGNOSTICS SPEC TEST (NEGATIVE)
|
||||
*
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
/*
|
||||
* KOTLIN DIAGNOSTICS SPEC TEST (NEGATIVE)
|
||||
*
|
||||
* SPEC VERSION: 0.1-152
|
||||
* PRIMARY LINKS: expressions, when-expression -> paragraph 5 -> sentence 1
|
||||
* expressions, when-expression -> paragraph 9 -> sentence 2
|
||||
* expressions, when-expression, exhaustive-when-expressions -> paragraph 1 -> sentence 1
|
||||
*/
|
||||
|
||||
|
||||
fun foo(x: Int) {
|
||||
return when (x) {
|
||||
2 -> {}
|
||||
3 -> {}
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
/*
|
||||
* KOTLIN DIAGNOSTICS SPEC TEST (NEGATIVE)
|
||||
*
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
/*
|
||||
* KOTLIN DIAGNOSTICS SPEC TEST (POSITIVE)
|
||||
*
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
/*
|
||||
* KOTLIN DIAGNOSTICS SPEC TEST (NEGATIVE)
|
||||
*
|
||||
* SPEC VERSION: 0.1-152
|
||||
* PRIMARY LINKS: expressions, when-expression -> paragraph 5 -> sentence 1
|
||||
* expressions, when-expression, exhaustive-when-expressions -> paragraph 1 -> sentence 1
|
||||
* expressions, when-expression, exhaustive-when-expressions -> paragraph 2 -> sentence 9
|
||||
*/
|
||||
|
||||
// See KT-6399: exhaustive whens on platform enums
|
||||
|
||||
// FILE: J.java
|
||||
|
||||
public enum J {
|
||||
A, B;
|
||||
|
||||
public static J create() {
|
||||
return J.A;
|
||||
}
|
||||
}
|
||||
|
||||
// FILE: K.kt
|
||||
|
||||
fun foo(): Int {
|
||||
// When is not-exhaustive
|
||||
return when (J.create()) {
|
||||
J.A -> 1
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
/*
|
||||
* KOTLIN DIAGNOSTICS SPEC TEST (NEGATIVE)
|
||||
*
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@
|
||||
enum class X { A, B }
|
||||
fun foo(arg: X?): Int {
|
||||
if (arg != null) {
|
||||
return when (arg) {
|
||||
return <!NO_ELSE_IN_WHEN!>when<!> (arg) {
|
||||
X.B -> 2
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
// !DIAGNOSTICS: -UNUSED_VARIABLE
|
||||
/*
|
||||
* KOTLIN DIAGNOSTICS SPEC TEST (NEGATIVE)
|
||||
*
|
||||
* SPEC VERSION: 0.1-152
|
||||
* PRIMARY LINKS: expressions, when-expression -> paragraph 5 -> sentence 1
|
||||
* expressions, when-expression -> paragraph 6 -> sentence 1
|
||||
* expressions, when-expression, exhaustive-when-expressions -> paragraph 2 -> sentence 6
|
||||
* expressions, when-expression, exhaustive-when-expressions -> paragraph 2 -> sentence 7
|
||||
* expressions, when-expression, exhaustive-when-expressions -> paragraph 2 -> sentence 8
|
||||
*/
|
||||
|
||||
sealed class A {
|
||||
class B: A() {
|
||||
class C: A()
|
||||
}
|
||||
}
|
||||
|
||||
class D: A()
|
||||
|
||||
fun test(a: A) {
|
||||
val nonExhaustive = when (a) {
|
||||
is A.B -> "B"
|
||||
is A.B.C -> "C"
|
||||
}
|
||||
|
||||
val exhaustive = when (a) {
|
||||
is A.B -> "B"
|
||||
is A.B.C -> "C"
|
||||
is D -> "D"
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// !DIAGNOSTICS: -UNUSED_VARIABLE
|
||||
/*
|
||||
* KOTLIN DIAGNOSTICS SPEC TEST (NEGATIVE)
|
||||
|
||||
+1
-1
@@ -27,7 +27,7 @@ fun foo(): Int {
|
||||
fun bar(): Int {
|
||||
val a = "a"
|
||||
if (a.length > 0) {
|
||||
return when (a) {
|
||||
return <!NO_ELSE_IN_WHEN!>when<!> (a) {
|
||||
"a" -> 1
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -38,4 +38,4 @@ fun test4() {
|
||||
2 -> bar(x, y)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
-18
@@ -1,18 +0,0 @@
|
||||
// !LANGUAGE: +VariableDeclarationInWhenSubject
|
||||
// !DIAGNOSTICS: -UNUSED_VARIABLE
|
||||
|
||||
enum class E { FIRST, SECOND }
|
||||
|
||||
fun testSmartcastToEnumInSubjectInitializer1(e: E?) {
|
||||
val x1 = when (val ne = e!!) {
|
||||
E.FIRST -> "f"
|
||||
E.SECOND -> "s"
|
||||
}
|
||||
}
|
||||
|
||||
fun testSmartcastToEnumInSubjectInitializer2(e: E?) {
|
||||
val x2 = when (val ne: Any = e!!) { // NB explicit type annotation
|
||||
E.FIRST -> "f"
|
||||
E.SECOND -> "s"
|
||||
}
|
||||
}
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// !LANGUAGE: +VariableDeclarationInWhenSubject
|
||||
// !DIAGNOSTICS: -UNUSED_VARIABLE
|
||||
|
||||
|
||||
-20
@@ -1,20 +0,0 @@
|
||||
// !LANGUAGE: +VariableDeclarationInWhenSubject
|
||||
// !DIAGNOSTICS: -UNUSED_VARIABLE
|
||||
|
||||
sealed class Either
|
||||
class Left : Either()
|
||||
class Right : Either()
|
||||
|
||||
fun testSmartcastToSealedInSubjectInitializer1(x: Any?) {
|
||||
val y1 = when (val either = x as Either) {
|
||||
is Left -> "L"
|
||||
is Right -> "R"
|
||||
}
|
||||
}
|
||||
|
||||
fun testSmartcastToSealedInSubjectInitializer2(x: Any?) {
|
||||
val y2 = when (val either: Any = x as Either) { // NB explicit type annotation
|
||||
is Left -> "L"
|
||||
is Right -> "R"
|
||||
}
|
||||
}
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// !LANGUAGE: +VariableDeclarationInWhenSubject
|
||||
// !DIAGNOSTICS: -UNUSED_VARIABLE
|
||||
|
||||
|
||||
Reference in New Issue
Block a user