diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosticCompilerTestFE10TestdataTestGenerated.java b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosticCompilerTestFE10TestdataTestGenerated.java index b158a191d74..9c4bae2f923 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosticCompilerTestFE10TestdataTestGenerated.java +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosticCompilerTestFE10TestdataTestGenerated.java @@ -8542,6 +8542,12 @@ public class DiagnosticCompilerTestFE10TestdataTestGenerated extends AbstractDia runTest("compiler/testData/diagnostics/tests/controlStructures/nestedLoopsWithMultipleLabels.kt"); } + @Test + @TestMetadata("noTypeMismatchWithWhenWithoutElse.kt") + public void testNoTypeMismatchWithWhenWithoutElse() throws Exception { + runTest("compiler/testData/diagnostics/tests/controlStructures/noTypeMismatchWithWhenWithoutElse.kt"); + } + @Test @TestMetadata("nonExhaustiveIfInElvis_after.kt") public void testNonExhaustiveIfInElvis_after() throws Exception { diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated.java b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated.java index f5beb5d7695..15b9a5aee33 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated.java +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated.java @@ -8542,6 +8542,12 @@ public class LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated runTest("compiler/testData/diagnostics/tests/controlStructures/nestedLoopsWithMultipleLabels.kt"); } + @Test + @TestMetadata("noTypeMismatchWithWhenWithoutElse.kt") + public void testNoTypeMismatchWithWhenWithoutElse() throws Exception { + runTest("compiler/testData/diagnostics/tests/controlStructures/noTypeMismatchWithWhenWithoutElse.kt"); + } + @Test @TestMetadata("nonExhaustiveIfInElvis_after.kt") public void testNonExhaustiveIfInElvis_after() throws Exception { diff --git a/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/negative/missingBooleanBranch.fir.txt b/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/negative/missingBooleanBranch.fir.txt index f37e990514e..dfebf512da6 100644 --- a/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/negative/missingBooleanBranch.fir.txt +++ b/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/negative/missingBooleanBranch.fir.txt @@ -1,12 +1,12 @@ FILE: missingBooleanBranch.kt public final fun test_1(cond: R|kotlin/Boolean|): R|kotlin/Unit| { - lval x: R|kotlin/Unit| = when (R|/cond|) { + lval x: R|kotlin/Int| = when (R|/cond|) { ==($subj$, Boolean(true)) -> { Int(1) } } - lval y: R|kotlin/Unit| = when (R|/cond|) { + lval y: R|kotlin/Int| = when (R|/cond|) { ==($subj$, Boolean(false)) -> { Int(2) } @@ -23,7 +23,7 @@ FILE: missingBooleanBranch.kt } public final fun test_2(cond: R|kotlin/Boolean?|): R|kotlin/Unit| { - lval x: R|kotlin/Unit| = when (R|/cond|) { + lval x: R|kotlin/Int| = when (R|/cond|) { ==($subj$, Boolean(true)) -> { Int(1) } diff --git a/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/negative/missingElse.fir.txt b/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/negative/missingElse.fir.txt index 791d4a1457f..60cd877097e 100644 --- a/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/negative/missingElse.fir.txt +++ b/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/negative/missingElse.fir.txt @@ -1,6 +1,6 @@ FILE: missingElse.kt public final fun test(a: R|kotlin/Any|): R|kotlin/Unit| { - lval x: R|kotlin/Unit| = when (R|/a|) { + lval x: R|kotlin/Int| = when (R|/a|) { ($subj$ is R|kotlin/Int|) -> { Int(1) } diff --git a/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/negative/missingEnumEntry.fir.txt b/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/negative/missingEnumEntry.fir.txt index 41862331832..f711c45048f 100644 --- a/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/negative/missingEnumEntry.fir.txt +++ b/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/negative/missingEnumEntry.fir.txt @@ -17,7 +17,7 @@ FILE: missingEnumEntry.kt } public final fun test_1(enum: R|SomeEnum|): R|kotlin/Unit| { - lval x: R|kotlin/Unit| = when (R|/enum|) { + lval x: R|kotlin/Int| = when (R|/enum|) { ==($subj$, Q|SomeEnum|.R|/SomeEnum.A|) -> { Int(1) } @@ -34,7 +34,7 @@ FILE: missingEnumEntry.kt } public final fun test_2(enum: R|SomeEnum?|): R|kotlin/Unit| { - lval x: R|kotlin/Unit| = when (R|/enum|) { + lval x: R|kotlin/Int| = when (R|/enum|) { ==($subj$, Q|SomeEnum|.R|/SomeEnum.A|) -> { Int(1) } diff --git a/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/negative/missingSealedInheritor.fir.txt b/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/negative/missingSealedInheritor.fir.txt index 6cb8362f9d3..f8986e5825e 100644 --- a/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/negative/missingSealedInheritor.fir.txt +++ b/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/negative/missingSealedInheritor.fir.txt @@ -20,13 +20,13 @@ FILE: b.kt } FILE: c.kt public final fun test_1(base: R|Base|): R|kotlin/Unit| { - lval x: R|kotlin/Unit| = when (R|/base|) { + lval x: R|kotlin/Int| = when (R|/base|) { ($subj$ is R|A|) -> { Int(1) } } - lval y: R|kotlin/Unit| = when (R|/base|) { + lval y: R|kotlin/Int| = when (R|/base|) { ==($subj$, Q|B|) -> { Int(1) } @@ -43,7 +43,7 @@ FILE: c.kt } public final fun test_2(base: R|Base?|): R|kotlin/Unit| { - lval x: R|kotlin/Unit| = when (R|/base|) { + lval x: R|kotlin/Int| = when (R|/base|) { ($subj$ is R|A|) -> { Int(1) } @@ -52,7 +52,7 @@ FILE: c.kt } } - lval y: R|kotlin/Unit| = when (R|/base|) { + lval y: R|kotlin/Int| = when (R|/base|) { ($subj$ is R|A|) -> { Int(1) } diff --git a/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveness_boolean.fir.txt b/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveness_boolean.fir.txt index 72efeabf878..6c6e4d7ef19 100644 --- a/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveness_boolean.fir.txt +++ b/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveness_boolean.fir.txt @@ -1,6 +1,6 @@ FILE: exhaustiveness_boolean.kt public final fun test_1(b: R|kotlin/Boolean|): R|kotlin/Unit| { - lval x: R|kotlin/Unit| = when (R|/b|) { + lval x: R|kotlin/Int| = when (R|/b|) { ==($subj$, Boolean(true)) -> { Int(1) } @@ -26,7 +26,7 @@ FILE: exhaustiveness_boolean.kt } public final fun test_2(b: R|kotlin/Boolean?|): R|kotlin/Unit| { - lval x: R|kotlin/Unit| = when (R|/b|) { + lval x: R|kotlin/Int| = when (R|/b|) { ==($subj$, Boolean(true)) -> { Int(1) } diff --git a/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveness_enum.fir.txt b/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveness_enum.fir.txt index f58fb4915bf..3e7ce0120af 100644 --- a/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveness_enum.fir.txt +++ b/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveness_enum.fir.txt @@ -18,7 +18,7 @@ FILE: exhaustiveness_enum.kt } public final fun test_1(e: R|Enum|): R|kotlin/Unit| { - lval a: R|kotlin/Unit| = when (R|/e|) { + lval a: R|kotlin/Int| = when (R|/e|) { ==($subj$, Q|Enum|.R|/Enum.A|) -> { Int(1) } @@ -27,7 +27,7 @@ FILE: exhaustiveness_enum.kt } } - lval b: R|kotlin/Unit| = when (R|/e|) { + lval b: R|kotlin/Int| = when (R|/e|) { ==($subj$, Q|Enum|.R|/Enum.A|) -> { Int(1) } @@ -62,7 +62,7 @@ FILE: exhaustiveness_enum.kt } public final fun test_2(e: R|Enum?|): R|kotlin/Unit| { - lval a: R|kotlin/Unit| = when (R|/e|) { + lval a: R|kotlin/Int| = when (R|/e|) { ==($subj$, Q|Enum|.R|/Enum.A|) -> { Int(1) } diff --git a/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveness_enumJava.fir.txt b/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveness_enumJava.fir.txt index 09164d980b2..edfb2a2ee45 100644 --- a/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveness_enumJava.fir.txt +++ b/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveness_enumJava.fir.txt @@ -1,6 +1,6 @@ FILE: main.kt public final fun test_1(e: R|JavaEnum|): R|kotlin/Unit| { - lval a: = when (R|/e|) { + lval a: R|kotlin/Int| = when (R|/e|) { ==($subj$, Q|JavaEnum|.R|/JavaEnum.A|) -> { Int(1) } @@ -8,8 +8,8 @@ FILE: main.kt Int(2) } } - .#(Int(0)) - lval b: = when (R|/e|) { + .R|kotlin/Int.plus|(Int(0)) + lval b: R|kotlin/Int| = when (R|/e|) { ==($subj$, Q|JavaEnum|.R|/JavaEnum.A|) -> { Int(1) } @@ -20,7 +20,7 @@ FILE: main.kt Int(3) } } - .#(Int(0)) + .R|kotlin/Int.plus|(Int(0)) lval c: R|kotlin/Int| = when (R|/e|) { ==($subj$, Q|JavaEnum|.R|/JavaEnum.A|) -> { Int(1) @@ -44,7 +44,7 @@ FILE: main.kt .R|kotlin/Int.plus|(Int(0)) } public final fun test_2(e: R|JavaEnum?|): R|kotlin/Unit| { - lval a: = when (R|/e|) { + lval a: R|kotlin/Int| = when (R|/e|) { ==($subj$, Q|JavaEnum|.R|/JavaEnum.A|) -> { Int(1) } @@ -55,7 +55,7 @@ FILE: main.kt Int(3) } } - .#(Int(0)) + .R|kotlin/Int.plus|(Int(0)) lval b: R|kotlin/Int| = when (R|/e|) { ==($subj$, Q|JavaEnum|.R|/JavaEnum.A|) -> { Int(1) diff --git a/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveness_enumJava.kt b/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveness_enumJava.kt index b5044dc32c2..f57414dd82c 100644 --- a/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveness_enumJava.kt +++ b/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveness_enumJava.kt @@ -10,13 +10,13 @@ fun test_1(e: JavaEnum) { val a = when (e) { JavaEnum.A -> 1 JavaEnum.B -> 2 - }.plus(0) + }.plus(0) val b = when (e) { JavaEnum.A -> 1 JavaEnum.B -> 2 is String -> 3 - }.plus(0) + }.plus(0) val c = when (e) { JavaEnum.A -> 1 @@ -35,7 +35,7 @@ fun test_2(e: JavaEnum?) { JavaEnum.A -> 1 JavaEnum.B -> 2 JavaEnum.C -> 3 - }.plus(0) + }.plus(0) val b = when (e) { JavaEnum.A -> 1 diff --git a/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveness_sealedClass.fir.txt b/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveness_sealedClass.fir.txt index 191f39b8b8b..28f01b0789b 100644 --- a/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveness_sealedClass.fir.txt +++ b/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveness_sealedClass.fir.txt @@ -26,7 +26,7 @@ FILE: exhaustiveness_sealedClass.kt } public final fun test_1(e: R|Base|): R|kotlin/Unit| { - lval a: R|kotlin/Unit| = when (R|/e|) { + lval a: R|kotlin/Int| = when (R|/e|) { ($subj$ is R|Base.A|) -> { Int(1) } @@ -35,7 +35,7 @@ FILE: exhaustiveness_sealedClass.kt } } - lval b: R|kotlin/Unit| = when (R|/e|) { + lval b: R|kotlin/Int| = when (R|/e|) { ($subj$ is R|Base.A|) -> { Int(1) } @@ -70,7 +70,7 @@ FILE: exhaustiveness_sealedClass.kt } public final fun test_2(e: R|Base?|): R|kotlin/Unit| { - lval a: R|kotlin/Unit| = when (R|/e|) { + lval a: R|kotlin/Int| = when (R|/e|) { ($subj$ is R|Base.A|) -> { Int(1) } diff --git a/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveness_sealedSubClass.fir.txt b/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveness_sealedSubClass.fir.txt index 3d03bb9d7c7..3ba046d0271 100644 --- a/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveness_sealedSubClass.fir.txt +++ b/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveness_sealedSubClass.fir.txt @@ -77,7 +77,7 @@ FILE: exhaustiveness_sealedSubClass.kt .R|kotlin/Int.plus|(Int(0)) } public final fun test_2(e: R|A|): R|kotlin/Unit| { - lval a: = when (R|/e|) { + lval a: R|kotlin/Int| = when (R|/e|) { ($subj$ is R|D|) -> { Int(1) } @@ -85,8 +85,8 @@ FILE: exhaustiveness_sealedSubClass.kt Int(2) } } - .#(Int(0)) - lval b: = when (R|/e|) { + .R|kotlin/Int.plus|(Int(0)) + lval b: R|kotlin/Int| = when (R|/e|) { ($subj$ is R|B|) -> { Int(1) } @@ -97,8 +97,8 @@ FILE: exhaustiveness_sealedSubClass.kt Int(3) } } - .#(Int(0)) - lval c: = when (R|/e|) { + .R|kotlin/Int.plus|(Int(0)) + lval c: R|kotlin/Int| = when (R|/e|) { ($subj$ is R|B|) -> { Int(1) } @@ -106,7 +106,7 @@ FILE: exhaustiveness_sealedSubClass.kt Int(2) } } - .#(Int(0)) + .R|kotlin/Int.plus|(Int(0)) lval d: R|kotlin/Int| = when (R|/e|) { ($subj$ is R|C|) -> { Int(1) diff --git a/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveness_sealedSubClass.kt b/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveness_sealedSubClass.kt index 0e3762dfeb1..65f2aac190b 100644 --- a/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveness_sealedSubClass.kt +++ b/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveness_sealedSubClass.kt @@ -35,18 +35,18 @@ fun test_2(e: A) { val a = when (e) { is D -> 1 is E -> 2 - }.plus(0) + }.plus(0) val b = when (e) { is B -> 1 is D -> 2 is E -> 3 - }.plus(0) + }.plus(0) val c = when (e) { is B -> 1 is D -> 2 - }.plus(0) + }.plus(0) val d = when (e) { is C -> 1 diff --git a/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveness_smartcastedBoolean.fir.txt b/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveness_smartcastedBoolean.fir.txt index 896053fc420..1ea0b5e3634 100644 --- a/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveness_smartcastedBoolean.fir.txt +++ b/compiler/fir/analysis-tests/testData/resolve/exhaustiveness/positive/exhaustiveness_smartcastedBoolean.fir.txt @@ -1,7 +1,7 @@ FILE: exhaustiveness_smartcastedBoolean.kt public final fun test_1(b: R|kotlin/Any|): R|kotlin/Unit| { R|kotlin/require|((R|/b| is R|kotlin/Boolean|)) - lval x: R|kotlin/Unit| = when (R|/b|) { + lval x: R|kotlin/Int| = when (R|/b|) { ==($subj$, Boolean(true)) -> { Int(1) } @@ -28,7 +28,7 @@ FILE: exhaustiveness_smartcastedBoolean.kt } public final fun test_2(b: R|kotlin/Any?|): R|kotlin/Unit| { R|kotlin/require|((R|/b| is R|kotlin/Boolean?|)) - lval x: R|kotlin/Unit| = when (R|/b|) { + lval x: R|kotlin/Int| = when (R|/b|) { ==($subj$, Boolean(true)) -> { Int(1) } diff --git a/compiler/fir/analysis-tests/testData/resolve/unqualifiedEnum/enumWithTheSameNameAsEntry.fir.txt b/compiler/fir/analysis-tests/testData/resolve/unqualifiedEnum/enumWithTheSameNameAsEntry.fir.txt index f966f8faa38..2b1f66480bf 100644 --- a/compiler/fir/analysis-tests/testData/resolve/unqualifiedEnum/enumWithTheSameNameAsEntry.fir.txt +++ b/compiler/fir/analysis-tests/testData/resolve/unqualifiedEnum/enumWithTheSameNameAsEntry.fir.txt @@ -16,7 +16,7 @@ FILE: enumWithTheSameNameAsEntry.kt public get(): R|kotlin/enums/EnumEntries| } - public final fun test(a: R|A|): R|kotlin/Unit| { + public final fun test(a: R|A|): R|kotlin/String| { ^test when (R|/a|) { ==($subj$, R|/A.A|.#) -> { String(A) diff --git a/compiler/fir/analysis-tests/testData/resolve/unqualifiedEnum/incorrectJava.fir.txt b/compiler/fir/analysis-tests/testData/resolve/unqualifiedEnum/incorrectJava.fir.txt index 119d6cfb215..a8a96c03af6 100644 --- a/compiler/fir/analysis-tests/testData/resolve/unqualifiedEnum/incorrectJava.fir.txt +++ b/compiler/fir/analysis-tests/testData/resolve/unqualifiedEnum/incorrectJava.fir.txt @@ -1,5 +1,5 @@ FILE: test.kt - public final fun foo(javaEnum: R|JavaEnum|): R|kotlin/Unit| { + public final fun foo(javaEnum: R|JavaEnum|): R|kotlin/Int| { ^foo when (R|/javaEnum|) { ==($subj$, #()) -> { Int(1) diff --git a/compiler/fir/analysis-tests/testData/resolve/unqualifiedEnum/priority.fir.txt b/compiler/fir/analysis-tests/testData/resolve/unqualifiedEnum/priority.fir.txt index a5cb00da40c..33894560903 100644 --- a/compiler/fir/analysis-tests/testData/resolve/unqualifiedEnum/priority.fir.txt +++ b/compiler/fir/analysis-tests/testData/resolve/unqualifiedEnum/priority.fir.txt @@ -42,7 +42,7 @@ FILE: second.kt } public final val ONE: R|second/Second| = Q|second/Second|.R|second/Second.THREE| public get(): R|second/Second| - public final fun foo(f: R|first/First|): R|kotlin/Unit| { + public final fun foo(f: R|first/First|): R|kotlin/Int| { ^foo when (R|/f|) { ==($subj$, R|second/ONE|) -> { Int(1) @@ -53,7 +53,7 @@ FILE: second.kt } } - public final fun bar(s: R|second/Second|): R|kotlin/Unit| { + public final fun bar(s: R|second/Second|): R|kotlin/Int| { ^bar when (R|/s|) { ==($subj$, R|first/THREE|) -> { Int(3) diff --git a/compiler/fir/analysis-tests/testData/resolve/whenElse.fir.txt b/compiler/fir/analysis-tests/testData/resolve/whenElse.fir.txt index f536bc827c1..fcfa4826de5 100644 --- a/compiler/fir/analysis-tests/testData/resolve/whenElse.fir.txt +++ b/compiler/fir/analysis-tests/testData/resolve/whenElse.fir.txt @@ -44,7 +44,7 @@ FILE: whenElse.kt } public final fun case2(): R|kotlin/Unit| { lval flag: R|kotlin/Any| = R|/get|(Boolean(false)) - lval l1: R|kotlin/Unit| = when (R|/flag|!!) { + lval l1: R|B| = when (R|/flag|!!) { ==($subj$, Q|A|.R|/A.A1|) -> { R|/B.B|() } @@ -53,7 +53,7 @@ FILE: whenElse.kt } } - lval l2: R|kotlin/Unit| = when (R|/flag|) { + lval l2: R|B| = when (R|/flag|) { ==($subj$, Q|A|.R|/A.A1|) -> { R|/B.B|() } @@ -65,7 +65,7 @@ FILE: whenElse.kt } public final fun case2(): R|kotlin/Unit| { lval flag: R|kotlin/Any| = R|/get|(Boolean(true)) - lval l1: R|kotlin/Unit| = when (R|/flag|!!) { + lval l1: R|B| = when (R|/flag|!!) { ==($subj$, Q|A|.R|/A.A1|) -> { R|/B.B|() } @@ -74,7 +74,7 @@ FILE: whenElse.kt } } - lval l2: R|kotlin/Unit| = when (R|/flag|) { + lval l2: R|B| = when (R|/flag|) { ==($subj$, Q|A|.R|/A.A1|) -> { R|/B.B|() } @@ -86,7 +86,7 @@ FILE: whenElse.kt } public final fun case3(): R|kotlin/Unit| { lval flag: R|kotlin/String| = String() - lval l1: R|kotlin/Unit| = when (R|/flag|!!) { + lval l1: R|B| = when (R|/flag|!!) { ==($subj$, Q|A|.R|/A.A1|) -> { R|/B.B|() } @@ -95,7 +95,7 @@ FILE: whenElse.kt } } - lval l2: R|kotlin/Unit| = when (R|/flag|) { + lval l2: R|B| = when (R|/flag|) { ==($subj$, Q|A|.R|/A.A1|) -> { R|/B.B|() } diff --git a/compiler/fir/analysis-tests/testData/resolve/whenExpressionType.fir.txt b/compiler/fir/analysis-tests/testData/resolve/whenExpressionType.fir.txt index 48b391966a8..41724ed6346 100644 --- a/compiler/fir/analysis-tests/testData/resolve/whenExpressionType.fir.txt +++ b/compiler/fir/analysis-tests/testData/resolve/whenExpressionType.fir.txt @@ -149,7 +149,7 @@ FILE: whenExpressionType.kt } public final fun case9(): R|kotlin/Unit| { lval flag: R|kotlin/Any| = Q|A|.R|/A.A1| - lval l1: R|kotlin/Unit| = when (R|/flag|) { + lval l1: R|B| = when (R|/flag|) { ==($subj$, Q|A|.R|/A.A1|) -> { R|/B.B|() } @@ -158,5 +158,5 @@ FILE: whenExpressionType.kt } } - lval x1: R|C| = R|/C.C#|(R|/l1|) + lval x1: R|C| = R|/C.C|(R|/l1|) } diff --git a/compiler/fir/analysis-tests/testData/resolve/whenExpressionType.kt b/compiler/fir/analysis-tests/testData/resolve/whenExpressionType.kt index 98392d64a6b..4ee94253bfe 100644 --- a/compiler/fir/analysis-tests/testData/resolve/whenExpressionType.kt +++ b/compiler/fir/analysis-tests/testData/resolve/whenExpressionType.kt @@ -106,6 +106,6 @@ fun case9() { A.A1 -> B() A.A2 -> B() } - val x1 = C(l1) + val x1 = C(l1) } diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLightTreeOldFrontendDiagnosticsTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLightTreeOldFrontendDiagnosticsTestGenerated.java index bcce93e2c88..e2fb139351f 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLightTreeOldFrontendDiagnosticsTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLightTreeOldFrontendDiagnosticsTestGenerated.java @@ -8536,6 +8536,12 @@ public class FirLightTreeOldFrontendDiagnosticsTestGenerated extends AbstractFir runTest("compiler/testData/diagnostics/tests/controlStructures/nestedLoopsWithMultipleLabels.kt"); } + @Test + @TestMetadata("noTypeMismatchWithWhenWithoutElse.kt") + public void testNoTypeMismatchWithWhenWithoutElse() throws Exception { + runTest("compiler/testData/diagnostics/tests/controlStructures/noTypeMismatchWithWhenWithoutElse.kt"); + } + @Test @TestMetadata("nonExhaustiveIfInElvis_after.kt") public void testNonExhaustiveIfInElvis_after() throws Exception { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiOldFrontendDiagnosticsTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiOldFrontendDiagnosticsTestGenerated.java index bfd87ab1a67..b7340c2972f 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiOldFrontendDiagnosticsTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiOldFrontendDiagnosticsTestGenerated.java @@ -8542,6 +8542,12 @@ public class FirPsiOldFrontendDiagnosticsTestGenerated extends AbstractFirPsiDia runTest("compiler/testData/diagnostics/tests/controlStructures/nestedLoopsWithMultipleLabels.kt"); } + @Test + @TestMetadata("noTypeMismatchWithWhenWithoutElse.kt") + public void testNoTypeMismatchWithWhenWithoutElse() throws Exception { + runTest("compiler/testData/diagnostics/tests/controlStructures/noTypeMismatchWithWhenWithoutElse.kt"); + } + @Test @TestMetadata("nonExhaustiveIfInElvis_after.kt") public void testNonExhaustiveIfInElvis_after() throws Exception { diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirControlFlowStatementsResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirControlFlowStatementsResolveTransformer.kt index 0b243ed0888..35187662778 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirControlFlowStatementsResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirControlFlowStatementsResolveTransformer.kt @@ -68,7 +68,9 @@ class FirControlFlowStatementsResolveTransformer(transformer: FirAbstractBodyRes var completionNeeded = false context.withWhenSubjectType(subjectType, components) { when { - whenExpression.branches.isEmpty() -> {} + whenExpression.branches.isEmpty() -> { + whenExpression.resultType = session.builtinTypes.unitType.type + } whenExpression.isOneBranch() && data.forceFullCompletion && data !is ResolutionMode.WithExpectedType -> { whenExpression = whenExpression.transformBranches(transformer, ResolutionMode.ContextIndependent) whenExpression.resultType = whenExpression.branches.first().result.resolvedType @@ -115,7 +117,7 @@ class FirControlFlowStatementsResolveTransformer(transformer: FirAbstractBodyRes } private fun FirWhenExpression.replaceReturnTypeIfNotExhaustive(): FirWhenExpression { - if (!isProperlyExhaustive) { + if (!isProperlyExhaustive && !usedAsExpression) { resultType = session.builtinTypes.unitType.type } return this diff --git a/compiler/testData/diagnostics/tests/controlStructures/ifWhenWithoutElse.fir.kt b/compiler/testData/diagnostics/tests/controlStructures/ifWhenWithoutElse.fir.kt index 1d6b11ecb1d..af53d87eb6a 100644 --- a/compiler/testData/diagnostics/tests/controlStructures/ifWhenWithoutElse.fir.kt +++ b/compiler/testData/diagnostics/tests/controlStructures/ifWhenWithoutElse.fir.kt @@ -11,18 +11,18 @@ val mlist = MList() fun work() {} val xx1 = if (true) 42 -val xx2: Unit = 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 xx5 = idUnit(if (true) 42) val xx6 = null ?: if (true) 42 val xx7 = "" + if (true) 42 val wxx1 = when { true -> 42 } -val wxx2: Unit = 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 wxx5 = idUnit(when { true -> 42 }) val wxx6 = null ?: when { true -> 42 } val wxx7 = "" + when { true -> 42 } @@ -57,7 +57,7 @@ fun foo1(x: String?) { "" + if (true) 42 w@while (true) { x ?: if (true) break - x ?: when { true -> break@w } + x ?: when { true -> break@w } } } diff --git a/compiler/testData/diagnostics/tests/controlStructures/noTypeMismatchWithWhenWithoutElse.fir.kt b/compiler/testData/diagnostics/tests/controlStructures/noTypeMismatchWithWhenWithoutElse.fir.kt new file mode 100644 index 00000000000..ac0332dc4e1 --- /dev/null +++ b/compiler/testData/diagnostics/tests/controlStructures/noTypeMismatchWithWhenWithoutElse.fir.kt @@ -0,0 +1,11 @@ +// ISSUE: KT-62069 + +enum class ExhaustiveEnum { ONE, TWO } + +fun exhaust(ee: ExhaustiveEnum) { + var v = 0 + v = when (ee) { + ExhaustiveEnum.ONE -> 1 + } + v = if (ee == ExhaustiveEnum.ONE) 2 +} diff --git a/compiler/testData/diagnostics/tests/controlStructures/noTypeMismatchWithWhenWithoutElse.kt b/compiler/testData/diagnostics/tests/controlStructures/noTypeMismatchWithWhenWithoutElse.kt new file mode 100644 index 00000000000..f2fadedec34 --- /dev/null +++ b/compiler/testData/diagnostics/tests/controlStructures/noTypeMismatchWithWhenWithoutElse.kt @@ -0,0 +1,11 @@ +// ISSUE: KT-62069 + +enum class ExhaustiveEnum { ONE, TWO } + +fun exhaust(ee: ExhaustiveEnum) { + var v = 0 + v = when (ee) { + ExhaustiveEnum.ONE -> 1 + } + v = if (ee == ExhaustiveEnum.ONE) 2 +} diff --git a/compiler/testData/diagnostics/tests/when/intersectionExhaustivenessComplex.fir.kt b/compiler/testData/diagnostics/tests/when/intersectionExhaustivenessComplex.fir.kt index 77c5cabe55f..033b950e7c1 100644 --- a/compiler/testData/diagnostics/tests/when/intersectionExhaustivenessComplex.fir.kt +++ b/compiler/testData/diagnostics/tests/when/intersectionExhaustivenessComplex.fir.kt @@ -38,5 +38,5 @@ fun foo(a: A) { when (a) { is A.A1 -> "" is B.B1 -> "..." - }.length + }.length } diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java index e386c710eb5..6bbaa83bc3d 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java @@ -8542,6 +8542,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest { runTest("compiler/testData/diagnostics/tests/controlStructures/nestedLoopsWithMultipleLabels.kt"); } + @Test + @TestMetadata("noTypeMismatchWithWhenWithoutElse.kt") + public void testNoTypeMismatchWithWhenWithoutElse() throws Exception { + runTest("compiler/testData/diagnostics/tests/controlStructures/noTypeMismatchWithWhenWithoutElse.kt"); + } + @Test @TestMetadata("nonExhaustiveIfInElvis_after.kt") public void testNonExhaustiveIfInElvis_after() throws Exception {