[FIR-TEST] Add new testdata generated after changes in previous commit

This commit is contained in:
Dmitriy Novozhilov
2019-12-11 16:16:22 +03:00
parent e9c02a1cca
commit 2536fa0cd5
4578 changed files with 104067 additions and 1 deletions
@@ -0,0 +1,8 @@
fun foo(a: Int) {
@ann
when (a) {
1 -> {}
}
}
annotation class ann
@@ -0,0 +1,12 @@
// !WITH_NEW_INFERENCE
class A
fun test(a: Any): String {
val q: String? = null
when (a) {
is A -> q!!
}
// When is not exhaustive
return q
}
@@ -0,0 +1,12 @@
// !WITH_NEW_INFERENCE
class A
fun test(a: Any) {
var q: String? = null
when (a) {
is A -> q = "1"
}
// When is not exhaustive
return q
}
@@ -0,0 +1,12 @@
enum class My { A, B }
fun test(a: My): String {
val q: String?
when (a) {
My.A -> q = "1"
My.B -> q = "2"
}
// When is exhaustive
return q
}
@@ -0,0 +1,12 @@
class A
fun test(a: Any): String {
var q: String?
when (a) {
is A -> q = "1"
else -> q = "2"
}
// When is not exhaustive
return q
}
@@ -0,0 +1,11 @@
fun foo(x: Int, y: Int): Int =
when {
x > 0, y > 0,<!SYNTAX!>,<!> x < 0 -> 1
else -> 0
}
fun bar(x: Int): Int =
when (x) {
0 -> 0
else -> 1
}
@@ -0,0 +1,51 @@
package test
const val four = 4
fun first(arg: Int) = when (arg) {
1 -> 2
2 -> 3
1 -> 4
4 -> 5
1 -> 6
2 -> 7
// Error should be here: see KT-11971
four -> 8
else -> 0
}
fun second(arg: String): Int {
when (arg) {
"ABC" -> return 0
"DEF" -> return 1
"ABC" -> return -1
"DEF" -> return -2
}
return 42
}
fun third(arg: Any?): Int {
when (arg) {
null -> return -1
is String -> return 0
is Double -> return 1
is Double -> return 2
null -> return 3
else -> return 5
}
}
enum class Color { RED, GREEN, BLUE }
fun fourth(arg: Color) = when (arg) {
Color.RED -> "RED"
Color.GREEN -> "GREEN"
Color.RED -> "BLUE"
Color.BLUE -> "BLUE"
}
fun fifth(arg: Any?) = when (arg) {
is Any -> "Any"
else -> ""
else -> null
}
@@ -0,0 +1,46 @@
// KT-2902 Check for null should be required when match nullable enum element
// FILE: 1.kt
enum class E { A, B }
fun test(e: E?) = when (e) {
E.A -> 1
E.B -> 2
}
fun withNull(e: E?) = when (e) {
E.A -> 3
E.B -> 4
null -> null
}
fun nullableNothing(): Nothing? = null
fun withNullableNothing(e: E?) = when (e) {
E.A -> 5
E.B -> 6
nullableNothing() -> null
}
fun platformType() = when (J.foo()) {
E.A -> 7
E.B -> 8
}
fun platformTypeSmartCast(): Int {
val e = J.foo()
if (e == null) return -1
return when (e) {
E.A -> 1
E.B -> 2
}
}
// FILE: J.java
class J {
static E foo() {
return E.A;
}
}
@@ -0,0 +1,11 @@
enum class E { A, B }
fun foo(e: E, something: Any?): Int {
if (something != null) return 0
return when (e) {
E.A -> 1
E.B -> 2
something -> 3
}
}
@@ -0,0 +1,8 @@
// EA-68871: empty when condition
fun foo(arg: Int): Int {
when (arg) {
0 -> return 0
<!SYNTAX!><!>-> return 4
else -> return -1
}
}
@@ -0,0 +1,9 @@
// EA-68871: empty when condition
enum class My { FIRST, SECOND }
fun foo(arg: My): Int {
when (arg) {
My.FIRST -> return 0
<!SYNTAX!><!>-> return 4
else -> return -1
}
}
@@ -0,0 +1,8 @@
// See also: KT-3743
fun foo(arg: Boolean): String {
// Must be exhaustive
return when(arg) {
true -> "truth"
false -> "falsehood"
}
}
@@ -0,0 +1,7 @@
fun foo(arg: Boolean): String {
// Must be exhaustive
return when(arg) {
(true) -> "truth"
((false)) -> "falsehood"
}
}
@@ -0,0 +1,8 @@
// See also: KT-3743
fun foo(arg: Boolean): String {
// Must be exhaustive
return when(arg) {
2 == 2 -> "truth"
2 == 1 -> "falsehood"
}
}
@@ -0,0 +1,9 @@
// See also: KT-3743
fun foo(arg: Boolean?): String {
// Must be exhaustive
return when(arg) {
true -> "truth"
false -> "falsehood"
null -> "unknown"
}
}
@@ -0,0 +1,14 @@
enum class Color { RED, GREEN, BLUE }
fun foo(arr: Array<Color>): Color {
loop@ for (color in arr) {
when (color) {
Color.RED -> return color
Color.GREEN -> break@loop
Color.BLUE -> if (arr.size == 1) return color else continue@loop
}
// Unreachable
return Color.BLUE
}
return Color.GREEN
}
@@ -0,0 +1,11 @@
enum class MyEnum {
A, B, C
}
fun foo(x: MyEnum): Int {
return when (x) {
is MyEnum.A -> 1
is MyEnum.B -> 2
is MyEnum.C -> 3
}
}
@@ -0,0 +1,11 @@
enum class MyEnum {
A, B, C
}
fun foo(x: MyEnum): Int {
return when (x) {
MyEnum.A -> 1
is MyEnum.B -> 2
is MyEnum.C -> 3
}
}
@@ -0,0 +1,15 @@
enum class Direction {
NORTH, SOUTH, WEST, EAST
}
fun foo(dir: Direction): Int {
val res: Int
// See KT-6046: res is always initialized
when (dir) {
Direction.NORTH -> res = 1
Direction.SOUTH -> res = 2
Direction.WEST -> res = 3
Direction.EAST -> res = 4
}
return res
}
@@ -0,0 +1,11 @@
fun foo(b: Boolean): Int {
val x: Int
val y: Int
when (b) {
true -> y = 1
false -> y = 0
}
// x is initialized here
x = 3
return x + y
}
@@ -0,0 +1,14 @@
enum class MyEnum {
A, B
}
fun foo(x: MyEnum?): Int {
val y: Int
// See KT-6046: y is always initialized
when (x) {
MyEnum.A -> y = 1
MyEnum.B -> y = 2
null -> y = 0
}
return y
}
@@ -0,0 +1,21 @@
// 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 exhaustive (count a platform enum as a special case)
return when (J.create()) {
J.A -> 1
J.B -> 2
}
}
@@ -0,0 +1,23 @@
// See KT-6399: exhaustive whens on platform enums
// FILE: J.java
import org.jetbrains.annotations.*;
public enum J {
A, B;
@NotNull public static J create() {
return J.A;
}
}
// FILE: K.kt
fun foo(): Int {
// When is exhaustive (count a platform enum as a special case)
return when (J.create()) {
J.A -> 1
J.B -> 2
}
}
@@ -0,0 +1,21 @@
// 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 {
return when (J.create()) {
J.A -> 1
J.B -> 2
else -> 0
}
}
@@ -0,0 +1,22 @@
// 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 exhaustive including null
return when (J.create()) {
J.A -> 1
J.B -> 2
null -> 0
}
}
@@ -0,0 +1,20 @@
// 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 (J.create()) {
J.A -> return 1
J.B -> return 2
}
}
@@ -0,0 +1,13 @@
enum class Direction {
NORTH, SOUTH, WEST, EAST
}
fun foo(dir: Direction): Int {
when (dir) {
Direction.NORTH -> return 1
Direction.SOUTH -> return 2
Direction.WEST -> return 3
Direction.EAST -> return 4
}
// See KT-1882: no return is needed at the end
}
@@ -0,0 +1,14 @@
enum class Direction {
NORTH, SOUTH, WEST, EAST
}
fun foo(dir: Direction): Int {
when (dir) {
Direction.NORTH -> return 1
Direction.SOUTH -> throw AssertionError("!!!")
Direction.WEST -> return 3
Direction.EAST -> return 4
}
// Error: Unreachable code. Return is not required.
if (dir == Direction.SOUTH) return 2
}
@@ -0,0 +1,22 @@
fun foo(a: Boolean, b: Boolean): Int {
val x: Int
if (a) {
x = 1
}
when (b) {
true -> x = 2
false -> x = 3
}
return x
}
fun bar(a: Boolean, b: Boolean): Int {
val x: Int
if (a) {
x = 1
}
when (b) {
false -> x = 3
}
return x
}
@@ -0,0 +1,22 @@
fun foo(a: Boolean, b: Boolean): Int {
var x: Int
if (a) {
x = 1
}
when (b) {
true -> x = 2
false -> x = 3
}
return x
}
fun bar(a: Boolean, b: Boolean): Int {
var x: Int
if (a) {
x = 1
}
when (b) {
false -> x = 3
}
return x
}
@@ -0,0 +1,14 @@
// KT-7857: when exhaustiveness does not take previous nullability checks into account
enum class X { A, B }
fun foo(arg: X?): Int {
if (arg != null) {
return when (arg) {
X.A -> 1
X.B -> 2
// else or null branch should not be required here!
}
}
else {
return 0
}
}
@@ -0,0 +1,12 @@
// KT-7857: when exhaustiveness does not take previous nullability checks into account
enum class X { A, B }
fun foo(arg: X?): Int {
if (arg == null) {
return 0
}
return when (arg) {
X.A -> 1
X.B -> 2
// else or null branch should not be required here!
}
}
@@ -0,0 +1,13 @@
// KT-7857: when exhaustiveness does not take previous nullability checks into account
fun foo(arg: Boolean?): Int {
if (arg != null) {
return when (arg) {
true -> 1
false -> 0
// else or null branch should not be required here!
}
}
else {
return -1
}
}
@@ -0,0 +1,14 @@
// KT-7857: when exhaustiveness does not take previous nullability checks into account
enum class X { A, B }
fun foo(arg: X?): Int {
if (arg == null) {
return 0
}
else {
return when (arg) {
X.A -> 1
X.B -> 2
// else or null branch should not be required here!
}
}
}
@@ -0,0 +1,7 @@
fun foo(x: Int) {
val y: Unit = when (x) {
2 -> {}
3 -> {}
}
return y
}
@@ -0,0 +1,6 @@
fun foo(x: Int): Any {
val v = when (x) {
2 -> 0
}
return v
}
@@ -0,0 +1,11 @@
fun foo(x: Int) {
r {
when (x) {
2 -> 0
}
}
}
fun r(f: () -> Unit) {
f()
}
@@ -0,0 +1,11 @@
fun foo(x: Int) {
r {
when (x) {
2 -> 0
}
}
}
fun r(f: () -> Int) {
f()
}
@@ -0,0 +1,5 @@
fun foo(x: Int): Any {
return when (x) {
2 -> 0
}
}
@@ -0,0 +1,6 @@
fun foo(x: Int) {
return when (x) {
2 -> {}
3 -> {}
}
}
@@ -0,0 +1,6 @@
fun foo(x: Int) {
when (x) {
2 -> {}
3 -> {}
}
}
@@ -0,0 +1,8 @@
// See also: KT-3743
fun foo(arg: Boolean?): String {
// Must be NOT exhaustive
return when(arg) {
true -> "truth"
false -> "falsehood"
}
}
@@ -0,0 +1,20 @@
// 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
}
}
@@ -0,0 +1,11 @@
// Base for KT-6227
enum class X { A, B, C, D }
fun foo(arg: X): String {
var res = "XXX"
when (arg) {
X.A -> res = "A"
X.B -> res = "B"
}
return res
}
@@ -0,0 +1,12 @@
// Base for KT-6227
enum class X { A, B, C, D }
fun foo(arg: X): String {
val res: String
when (arg) {
X.A -> res = "A"
X.B -> res = "B"
else -> res = "CD"
}
return res
}
@@ -0,0 +1,13 @@
// Base for KT-6227
enum class X { A, B, C, D }
fun foo(arg: X): String {
val res: String
when (arg) {
X.A -> res = "A"
X.B -> res = "B"
X.C -> res = "C"
X.D -> res = "D"
}
return res
}
@@ -0,0 +1,16 @@
sealed class S
object First : S()
class Derived(val s: String) : S()
object Last : S()
fun use(s: String) = s
fun foo(s: S) {
when (s) {
First -> {}
is Derived -> use(s.s)
}
}
@@ -0,0 +1,14 @@
// Base for KT-6227
enum class X { A, B, C, D }
fun foo(arg: X?): String {
var res = "XXX"
// Should we report something here? Probably not, null is not an enum entry
when (arg) {
X.A -> res = "A"
X.B -> res = "B"
X.C -> res = "C"
X.D -> res = "D"
}
return res
}
@@ -0,0 +1,12 @@
// KT-7857: when exhaustiveness does not take previous nullability checks into account
enum class X { A, B }
fun foo(arg: X?): Int {
if (arg != null) {
return when (arg) {
X.B -> 2
}
}
else {
return 0
}
}
@@ -0,0 +1,16 @@
// See KT-5113
enum class E {
A,
B
}
class Outer(e: E) {
private val prop: Int
init {
when(e ) {
// When is exhaustive, property is always initialized
E.A -> prop = 1
E.B -> prop = 2
}
}
}
@@ -0,0 +1,68 @@
// FILE: MyEnum.java
public enum MyEnum {
SINGLE;
public static MyEnum getInstance() {
return SINGLE;
}
}
// FILE: test.kt
sealed class X {
class A : X()
class B : X()
}
fun foo(x: X) = when (x) {
is X.A -> {}
is X.B -> {}
else -> {}
}
fun bar(x: X?): String = when (x) {
is X.A -> "A"
is X.B -> "B"
null -> "null"
else -> "Unreachable"
}
fun justUse(x: X) {
when (x) {
is X.A -> {}
is X.B -> {}
// Redundant even in statement position
else -> {}
}
}
enum class E {
A, B
}
fun foo(e: E): String = when (e) {
E.A -> "A"
E.B -> "B"
else -> ""
}
fun bar(e: E?): String = when (e) {
E.A -> "A"
E.B -> "B"
else -> "" // no warning
}
fun foo(b: Boolean) = when (b) {
true -> 1
false -> 0
else -> -1
}
fun useJava(): String {
val me = MyEnum.getInstance()
return when (me) {
MyEnum.SINGLE -> "OK"
else -> "FAIL" // no warning
}
}
@@ -0,0 +1,37 @@
// !DIAGNOSTICS: -UNUSED_PARAMETER
infix fun Any.sealed(a: Any?) {}
val x = 1 sealed when (1) {
1 -> 1
else -> 2
}
val x1 = 1 sealed /**/ when (1) {
1 -> 1
else -> 2
}
fun foo() {
<!UNRESOLVED_REFERENCE!>sealed<!><!SYNTAX!><!> when {
else -> {}
}
1 sealed when {
else -> {}
}
1 sealed (when {
else -> {}
})
1
<!UNRESOLVED_REFERENCE!>sealed<!><!SYNTAX!><!> when {
else -> {}
}
1 sealed
when {
else -> {}
}
}
@@ -0,0 +1,22 @@
// !DIAGNOSTICS: -UNUSED_VARIABLE
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"
}
}
+46
View File
@@ -0,0 +1,46 @@
// !WITH_NEW_INFERENCE
fun Int.foo() : Boolean = true
fun foo() : Int {
val s = ""
val x = 1
when (x) {
is String -> 1
!is Int -> 1
is Any? -> 1
is Any -> 1
s -> 1
1 -> 1
1 <!AMBIGUITY!>+<!> <!UNRESOLVED_REFERENCE!>a<!> -> 1
in 1..<!UNRESOLVED_REFERENCE!>a<!> -> 1
!in 1..<!UNRESOLVED_REFERENCE!>a<!> -> 1
else -> 1
}
return 0
}
val _type_test : Int = foo() // this is needed to ensure the inferred return type of foo()
fun test() {
val x = 1;
val s = "";
when (x) {
s -> 1
"" -> 1
x -> 1
1 -> 1
}
val z = 1
when (z) {
else -> 1
1 -> 2
}
when (z) {
else -> 1
}
}
@@ -0,0 +1,21 @@
fun foo(s: Any): String {
val x = when (s) {
is String -> s
is Int -> "$s"
else -> return ""
}
val y: String = x // should be Ok
return y
}
fun bar(s: Any): String {
val x = when (s) {
is String -> s as String // meaningless
is Int -> "$s"
else -> return ""
}
val y: String = x // no error
return y
}
+13
View File
@@ -0,0 +1,13 @@
// !WITH_NEW_INFERENCE
fun foo(x: Int) = x
fun test0(flag: Boolean) {
<!INAPPLICABLE_CANDIDATE!>foo<!>(if (flag) true else "")
}
fun test1(flag: Boolean) {
<!INAPPLICABLE_CANDIDATE!>foo<!>(when (flag) {
true -> true
else -> ""
})
}
+52
View File
@@ -0,0 +1,52 @@
// !WITH_NEW_INFERENCE
// !DIAGNOSTICS: -UNUSED_PARAMETER -DEBUG_INFO_SMARTCAST
// NI_EXPECTED_FILE
interface Data
interface Item
class FlagData(val value: Boolean) : Data
class ListData<T : Item>(val list: List<T>) : Data
fun <T> listOf(vararg items: T): List<T> = null!!
fun test1(o: Any) = when (o) {
is List<*> ->
ListData(listOf())
is Int -> when {
o < 0 ->
FlagData(true)
else ->
null
}
else ->
null
}
fun test1x(o: Any): Data? = when (o) {
is List<*> ->
ListData(listOf())
is Int -> when {
o < 0 ->
FlagData(true)
else ->
null
}
else ->
null
}
fun test2() =
if (true)
ListData(listOf())
else
FlagData(true)
fun test2x(): Data =
if (true) ListData(listOf()) else FlagData(true)
fun test2y(): Any =
if (true) ListData(listOf()) else FlagData(true)
fun test2z(): Any =
run { if (true) ListData(listOf()) else FlagData(true) }
+24
View File
@@ -0,0 +1,24 @@
interface Maybe<T>
class Some<T>(val value: T) : Maybe<T>
class None<T> : Maybe<T>
fun <T> none() : None<T> = TODO()
fun test1() : Maybe<String?> = if (true) none() else Some("")
fun test2() : Maybe<String?> = when {
true -> none()
else -> Some("")
}
fun test3() : Maybe<String?> = when {
true -> none()
else -> Some<String?>("")
}
fun test4() : Maybe<String?> {
when ("") {
"a" -> return none()
else -> return Some<String?>("")
}
}
+27
View File
@@ -0,0 +1,27 @@
// KT-4434 Missed diagnostic about else branch in when
package test
fun foo(): Int {
val a = "a"
return if (a.length > 0) {
when (a) {
"a" -> 1
}
}
else {
3
}
}
fun bar(): Int {
val a = "a"
if (a.length > 0) {
return when (a) {
"a" -> 1
}
}
else {
return 3
}
}
+10
View File
@@ -0,0 +1,10 @@
// !WITH_NEW_INFERENCE
val test: Int = if (true) {
when (2) {
1 -> 1
else -> null
}
}
else {
2
}
+18
View File
@@ -0,0 +1,18 @@
// !WITH_NEW_INFERENCE
fun test1(): Int {
val x: String = if (true) {
when {
true -> Any()
else -> null
}
} else ""
return x.hashCode()
}
fun test2(): Int {
val x: String = when {
true -> Any()
else -> null
} ?: return 0
return x.hashCode()
}
@@ -0,0 +1,25 @@
// !WITH_NEW_INFERENCE
val test1: (String) -> Boolean =
when {
true -> {{ true }}
else -> {{ false }}
}
val test2: (String) -> Boolean =
when {
true -> {{ true }}
else -> null!!
}
val test3: (String) -> Boolean =
when {
true -> { s -> true }
else -> null!!
}
val test4: (String) -> Boolean =
when {
true -> { s1, s2 -> true }
else -> null!!
}
@@ -0,0 +1,39 @@
// !WITH_NEW_INFERENCE
// NI_EXPECTED_FILE
val test1 = when {
true -> { { true } }
else -> TODO()
}
val test1a: () -> Boolean = when {
true -> { { true } }
else -> TODO()
}
val test2 = when {
true -> { { true } }
else -> when {
true -> { { true } }
else -> TODO()
}
}
val test2a: () -> Boolean = when {
true -> { { true } }
else -> when {
true -> { { true } } // TODO
else -> TODO()
}
}
val test3 = when {
true -> { { true } }
true -> { { true } }
else -> TODO()
}
val test3a: () -> Boolean = when {
true -> { { true } }
true -> { { true } }
else -> TODO()
}
@@ -0,0 +1,37 @@
// !LANGUAGE: +VariableDeclarationInWhenSubject
// !DIAGNOSTICS: -UNUSED_VARIABLE
fun getBoolean() = true
fun testSafeCaptureVarInInitializer() {
var x: Int? = 42
x!!
x.inc()
val s = when (val y = run { x = 42; 32 }) {
0 -> {
x.inc() // TODO fix smart casts for captured variables
"0"
}
else -> "!= 0"
}
x.inc() // TODO fix smart casts for captured variables
}
fun testUnsafeCaptureVarInInitializer() {
var x: Int? = 42
x!!
x.inc()
val s = when (val y = run { x = null; 32 }) {
0 -> {
x.<!UNRESOLVED_REFERENCE!>inc<!>() // NB smart cast should be impossible
"0"
}
else -> "!= 0"
}
x.<!UNRESOLVED_REFERENCE!>inc<!>() // NB smart cast should be impossible
}
@@ -0,0 +1,14 @@
// !LANGUAGE: +VariableDeclarationInWhenSubject
// !DIAGNOSTICS: -UNUSED_VARIABLE
fun foo(): Any = 42
fun test(x: Any) {
val z1 = when (val y = foo()) {
42 -> "Magic: $y, $x"
else -> {
"Not magic: $y, $x"
}
}
val z2 = "Anyway, it was $<!UNRESOLVED_REFERENCE!>y<!>"
}
@@ -0,0 +1,43 @@
// !LANGUAGE: +VariableDeclarationInWhenSubject
// !DIAGNOSTICS: -UNUSED_VARIABLE
fun testJumpOutInElvis(x: Int?) {
loop@ while (true) {
val y = when (val z = x ?: break@loop) {
0 -> "0"
else -> "not 0"
}
x.inc()
}
x.<!INAPPLICABLE_CANDIDATE!>inc<!>()
}
fun testJumpOutInElvisLikeIf(x: Int?) {
loop@ while (true) {
val y = when (val z = if (x == null) break@loop else x) {
0 -> "0"
else -> "not 0"
}
x.inc()
}
x.<!INAPPLICABLE_CANDIDATE!>inc<!>()
}
fun getBoolean() = true
fun testJumpOutInIf(x: Int?) {
loop@ while (true) {
val y = when (val z = if (getBoolean()) { x!!; break@loop } else x) {
0 -> "0"
else -> "not 0"
}
x.<!INAPPLICABLE_CANDIDATE!>inc<!>()
}
x.inc() // Actually, safe, but it's OK if it's error
}
@@ -0,0 +1,41 @@
// !LANGUAGE: +VariableDeclarationInWhenSubject
// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER -UNUSED_VALUE
fun foo() {}
fun <T> bar(x: T, y: T) {}
fun test1() {
when (1) {
1 ->
when (val y = 2) {
2 -> foo()
}
}
}
fun test2() {
when (val x = 1) {
1 ->
when (val y = 2) {
2 -> foo()
}
}
}
fun test3() {
when (val x = 1) {
1 ->
when (val x = 2) {
2 -> foo()
}
}
}
fun test4() {
when (val x = 1) {
1 ->
when (val y = 2) {
2 -> bar(x, y)
}
}
}
@@ -0,0 +1,10 @@
// !LANGUAGE: +VariableDeclarationInWhenSubject
// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER
fun testNoSubjectVariableName(x: Int?) {
val y = when (val<!SYNTAX!><!> = 42) {
0 -> "0"
else -> "not 0"
}
}
@@ -0,0 +1,10 @@
// !LANGUAGE: +VariableDeclarationInWhenSubject
// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER -UNUSED_VALUE
fun foo(): Any = 42
fun test1(x: Any) {
when (val y = foo()) {
is String -> y = ""
}
}
@@ -0,0 +1,27 @@
// !LANGUAGE: +VariableDeclarationInWhenSubject
// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER
fun foo(): Any = 42
fun useInt(i: Int) {}
fun testShadowingParameter(y: Any) {
when (val y = foo()) {
else -> {}
}
}
fun testShadowedInWhenBody(x: Any) {
when (val y = x) {
is String -> {
val y = y.length
useInt(y)
}
}
}
fun testShadowinLocalVariable() {
val y = foo()
when (val y = foo()) {
else -> {}
}
}
@@ -0,0 +1,49 @@
// !LANGUAGE: +VariableDeclarationInWhenSubject
// !WITH_NEW_INFERENCE
fun foo(s1: Int, s2: Int) = s1 + s2
fun test1(x: String?) =
when (val y = x?.length) {
null -> 0
else -> foo(x.length, y)
}
fun test2(x: String?) {
when (val y = run { x!! }) {
"foo" -> x.length
"bar" -> y.length
}
}
fun test3(x: String?, y: String?) {
when (val z = x ?: y!!) {
"foo" -> x.<!INAPPLICABLE_CANDIDATE!>length<!>
"bar" -> y.<!INAPPLICABLE_CANDIDATE!>length<!>
"baz" -> z.length
}
}
fun <T> id(x: T): T = x
fun test4(x: String?) {
when (val y = id(x!!)) {
"foo" -> x.length
"bar" -> y.length
}
}
class Inv<T>(val data: T)
fun test5(x: Inv<out Any?>) {
when (val y = x.data) {
is String -> y.length // should be ok
null -> x.data.<!UNRESOLVED_REFERENCE!>length<!> // should be error
}
}
fun test6(x: Inv<out String?>) {
when (val y = x.data) {
is String -> x.data.length // should be ok
}
}
@@ -0,0 +1,8 @@
// !LANGUAGE: +VariableDeclarationInWhenSubject
fun test(x: Any?) =
when (val y = x) {
is String -> "String, length = ${y.length}"
null -> "Null"
else -> "Any, hashCode = ${y.hashCode()}"
}
@@ -0,0 +1,18 @@
// !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"
}
}
@@ -0,0 +1,20 @@
// !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"
}
}
@@ -0,0 +1,7 @@
// !LANGUAGE: +VariableDeclarationInWhenSubject
fun test(data: String) =
when (data.length) {
0 -> -1
else -> 42
}
@@ -0,0 +1,8 @@
// !LANGUAGE: +VariableDeclarationInWhenSubject
// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER
fun test(x: Any) {
when (val y = x) {
is String -> {}
}
}
@@ -0,0 +1,16 @@
// !LANGUAGE: -VariableDeclarationInWhenSubject
// !DIAGNOSTICS: -UNUSED_VARIABLE
fun foo(): Any = 42
fun test(x: Any) {
// NB check that we still resolve 'y', even though current language version doesn' support variable declaration in when subject
val z1 = when (val y = foo()) {
42 -> "Magic: $y, $x"
else -> {
"Not magic: $y, $x"
}
}
val z2 = "Anyway, it was $<!UNRESOLVED_REFERENCE!>y<!>"
}
@@ -0,0 +1,29 @@
// !LANGUAGE: +VariableDeclarationInWhenSubject
// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER
// WITH_RUNTIME
fun foo(): Any = 42
fun String.bar(): Any = 42
fun testSimpleValInWhenSubject() {
when (val y = foo()) {
}
}
fun testValWithoutInitializerWhenSubject() {
when (val y: Any) {
is String -> y.<!UNRESOLVED_REFERENCE!>length<!>
}
}
fun testVarInWhenSubject() {
when (var y = foo()) {
is String -> y.length
}
}
fun testDelegatedValInWhenSubject() {
when (val y by lazy { 42 }) {
}
}
@@ -0,0 +1,8 @@
// !LANGUAGE: +VariableDeclarationInWhenSubject
fun foo(): Any = 42
fun test() {
when (val x = foo()) {
}
}