diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ExpressionCodegen.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ExpressionCodegen.kt index 5481bb1f7e5..97a7d0bc87d 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ExpressionCodegen.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ExpressionCodegen.kt @@ -590,9 +590,6 @@ class ExpressionCodegen( val endLabel = Label() val exhaustive = expression.branches.any { it.condition.isTrueConst() } - assert(exhaustive || expression.type.isUnit() || expression.type.isNothing()) { - "non-exhaustive conditional should return Unit: ${expression.dump()}" - } for (branch in expression.branches) { val elseLabel = Label() if (branch.condition.isFalseConst() || branch.condition.isTrueConst()) { @@ -619,6 +616,14 @@ class ExpressionCodegen( mv.mark(elseLabel) } mv.mark(endLabel) + // NOTE: using a non-exhaustive if/when as an expression is invalid, so it should theoretically + // always return Unit. However, with the current frontend this is not always the case. + // Most notably, 1. when all branches return/break/continue, the type is Nothing; + // 2. the frontend may sometimes infer Any instead of Unit, probably due to a bug + // (see compiler/testData/codegen/box/controlStructures/ifIncompatibleBranches.kt). + // It should still be safe to produce a soon-to-be-discarded Unit. (What is not ok is + // inserting *any* code here, though, as its line number will be that of the last line + // of the last branch.) return immaterialUnitValue } diff --git a/compiler/testData/codegen/box/controlStructures/ifIncompatibleBranches.kt b/compiler/testData/codegen/box/controlStructures/ifIncompatibleBranches.kt new file mode 100644 index 00000000000..93cd9b07c57 --- /dev/null +++ b/compiler/testData/codegen/box/controlStructures/ifIncompatibleBranches.kt @@ -0,0 +1,10 @@ +fun box(): String { + var s = "2" + var res = "Fail" + if (s == "1") { + false + } else if (s == "2") { + res = "OK" + } + return res +} diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index eb642dc28dd..2c6feb4038c 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -4838,6 +4838,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/controlStructures/ifConst2.kt"); } + @TestMetadata("ifIncompatibleBranches.kt") + public void testIfIncompatibleBranches() throws Exception { + runTest("compiler/testData/codegen/box/controlStructures/ifIncompatibleBranches.kt"); + } + @TestMetadata("inRangeConditionsInWhen.kt") public void testInRangeConditionsInWhen() throws Exception { runTest("compiler/testData/codegen/box/controlStructures/inRangeConditionsInWhen.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index ef49e099353..4a03248adcd 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -4838,6 +4838,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTest("compiler/testData/codegen/box/controlStructures/ifConst2.kt"); } + @TestMetadata("ifIncompatibleBranches.kt") + public void testIfIncompatibleBranches() throws Exception { + runTest("compiler/testData/codegen/box/controlStructures/ifIncompatibleBranches.kt"); + } + @TestMetadata("inRangeConditionsInWhen.kt") public void testInRangeConditionsInWhen() throws Exception { runTest("compiler/testData/codegen/box/controlStructures/inRangeConditionsInWhen.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java index a4c9b530449..1a46a991f81 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java @@ -4808,6 +4808,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/controlStructures/ifConst2.kt"); } + @TestMetadata("ifIncompatibleBranches.kt") + public void testIfIncompatibleBranches() throws Exception { + runTest("compiler/testData/codegen/box/controlStructures/ifIncompatibleBranches.kt"); + } + @TestMetadata("inRangeConditionsInWhen.kt") public void testInRangeConditionsInWhen() throws Exception { runTest("compiler/testData/codegen/box/controlStructures/inRangeConditionsInWhen.kt"); diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java index e1998f4fc80..9af806924fd 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java @@ -3963,6 +3963,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest { runTest("compiler/testData/codegen/box/controlStructures/ifConst2.kt"); } + @TestMetadata("ifIncompatibleBranches.kt") + public void testIfIncompatibleBranches() throws Exception { + runTest("compiler/testData/codegen/box/controlStructures/ifIncompatibleBranches.kt"); + } + @TestMetadata("inRangeConditionsInWhen.kt") public void testInRangeConditionsInWhen() throws Exception { runTest("compiler/testData/codegen/box/controlStructures/inRangeConditionsInWhen.kt"); diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java index b1590521a61..cdee47d8585 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java @@ -3973,6 +3973,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { runTest("compiler/testData/codegen/box/controlStructures/ifConst2.kt"); } + @TestMetadata("ifIncompatibleBranches.kt") + public void testIfIncompatibleBranches() throws Exception { + runTest("compiler/testData/codegen/box/controlStructures/ifIncompatibleBranches.kt"); + } + @TestMetadata("inRangeConditionsInWhen.kt") public void testInRangeConditionsInWhen() throws Exception { runTest("compiler/testData/codegen/box/controlStructures/inRangeConditionsInWhen.kt");