[FIR] Implement checker for exhaustive when's in expression position
This commit is contained in:
@@ -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 {
|
||||
|
||||
|
||||
Reference in New Issue
Block a user