Do not throw an exception when a when-statement with no else makes no match
This commit is contained in:
@@ -3725,7 +3725,17 @@ The "returned" value of try expression with no finally is either the last expres
|
||||
}
|
||||
if (!hasElse && nextCondition != null) {
|
||||
v.mark(nextCondition);
|
||||
throwNewException(CLASS_NO_PATTERN_MATCHED_EXCEPTION);
|
||||
if (!isStatement) {
|
||||
// a result is expected
|
||||
if (Boolean.TRUE.equals(bindingContext.get(BindingContext.EXHAUSTIVE_WHEN, expression))) {
|
||||
// when() is supposed to be exhaustive
|
||||
throwNewException(CLASS_NO_PATTERN_MATCHED_EXCEPTION);
|
||||
}
|
||||
else {
|
||||
// non-exhaustive when() with no else -> Unit must be expected
|
||||
StackValue.putUnitInstance(v);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
markLineNumber(expression);
|
||||
|
||||
@@ -65,7 +65,11 @@ public final class WhenChecker {
|
||||
}
|
||||
}
|
||||
}
|
||||
return isExhaust && notEmpty;
|
||||
boolean exhaustive = isExhaust && notEmpty;
|
||||
if (exhaustive) {
|
||||
trace.record(BindingContext.EXHAUSTIVE_WHEN, expression);
|
||||
}
|
||||
return exhaustive;
|
||||
}
|
||||
|
||||
private static boolean containsEnumEntryCase(
|
||||
|
||||
@@ -110,6 +110,8 @@ public interface BindingContext {
|
||||
|
||||
WritableSlice<JetExpression, JetType> AUTOCAST = Slices.createSimpleSlice();
|
||||
|
||||
WritableSlice<JetWhenExpression, Boolean> EXHAUSTIVE_WHEN = Slices.createSimpleSlice();
|
||||
|
||||
/**
|
||||
* A scope where type of expression has been resolved
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
fun box(): String {
|
||||
var r = "OK"
|
||||
val x = 3
|
||||
val y: Unit = when (x) {
|
||||
1 -> { r = "Fail 0" }
|
||||
2 -> { r = "Fail 1" }
|
||||
}
|
||||
return r
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
enum class En {
|
||||
A
|
||||
B
|
||||
}
|
||||
|
||||
fun box(): String = when(En.A) {
|
||||
En.A -> "OK"
|
||||
En.B -> "Fail 1"
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
enum class En {
|
||||
A
|
||||
B
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
when(En.A) {
|
||||
En.A -> "s1"
|
||||
En.B -> "s2"
|
||||
}
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
enum class En {
|
||||
A
|
||||
B
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
|
||||
val u: Unit = when(En.A) {
|
||||
En.A -> {}
|
||||
En.B -> {}
|
||||
}
|
||||
|
||||
return "OK"
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
var r = "OK"
|
||||
|
||||
fun foo(x: Int) {
|
||||
return when (x) {
|
||||
1 -> { r = "Fail" }
|
||||
}
|
||||
}
|
||||
fun box(): String {
|
||||
foo(0)
|
||||
return r
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
fun box(): String {
|
||||
val x = 3
|
||||
when (x) {
|
||||
1 -> {}
|
||||
2 -> {}
|
||||
}
|
||||
return "OK"
|
||||
}
|
||||
@@ -4413,16 +4413,46 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
doTest("compiler/testData/codegen/box/when/noElseAssigned.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("noElseAssignedNoMatch.kt")
|
||||
public void testNoElseAssignedNoMatch() throws Exception {
|
||||
doTest("compiler/testData/codegen/box/when/noElseAssignedNoMatch.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("noElseExhaustive.kt")
|
||||
public void testNoElseExhaustive() throws Exception {
|
||||
doTest("compiler/testData/codegen/box/when/noElseExhaustive.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("noElseExhaustiveStatement.kt")
|
||||
public void testNoElseExhaustiveStatement() throws Exception {
|
||||
doTest("compiler/testData/codegen/box/when/noElseExhaustiveStatement.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("noElseExhaustiveUnitExpected.kt")
|
||||
public void testNoElseExhaustiveUnitExpected() throws Exception {
|
||||
doTest("compiler/testData/codegen/box/when/noElseExhaustiveUnitExpected.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("noElseInRetunedExpression.kt")
|
||||
public void testNoElseInRetunedExpression() throws Exception {
|
||||
doTest("compiler/testData/codegen/box/when/noElseInRetunedExpression.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("noElseInRetunedExpressionNoMatch.kt")
|
||||
public void testNoElseInRetunedExpressionNoMatch() throws Exception {
|
||||
doTest("compiler/testData/codegen/box/when/noElseInRetunedExpressionNoMatch.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("noElseInStatement.kt")
|
||||
public void testNoElseInStatement() throws Exception {
|
||||
doTest("compiler/testData/codegen/box/when/noElseInStatement.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("noElseNoMatch.kt")
|
||||
public void testNoElseNoMatch() throws Exception {
|
||||
doTest("compiler/testData/codegen/box/when/noElseNoMatch.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("nullableWhen.kt")
|
||||
public void testNullableWhen() throws Exception {
|
||||
doTest("compiler/testData/codegen/box/when/nullableWhen.kt");
|
||||
|
||||
Reference in New Issue
Block a user