diff --git a/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/fir/Fir2IrTextTestGenerated.java b/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/fir/Fir2IrTextTestGenerated.java index ca1c2e38875..5a6cb536a12 100644 --- a/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/fir/Fir2IrTextTestGenerated.java +++ b/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/fir/Fir2IrTextTestGenerated.java @@ -1267,6 +1267,11 @@ public class Fir2IrTextTestGenerated extends AbstractFir2IrTextTest { runTest("compiler/testData/ir/irText/expressions/whenReturn.kt"); } + @TestMetadata("whenUnusedExpression.kt") + public void testWhenUnusedExpression() throws Exception { + runTest("compiler/testData/ir/irText/expressions/whenUnusedExpression.kt"); + } + @TestMetadata("whenWithSubjectVariable.kt") public void testWhenWithSubjectVariable() throws Exception { runTest("compiler/testData/ir/irText/expressions/whenWithSubjectVariable.kt"); diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/BranchingExpressionGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/BranchingExpressionGenerator.kt index fbc062c3d6c..ed2627275fc 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/BranchingExpressionGenerator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/BranchingExpressionGenerator.kt @@ -104,11 +104,9 @@ class BranchingExpressionGenerator(statementGenerator: StatementGenerator) : Sta val inferredType = getInferredTypeWithImplicitCastsOrFail(expression) - // TODO relies on ControlFlowInformationProvider, get rid of it - val isUsedAsExpression = get(BindingContext.USED_AS_EXPRESSION, expression) ?: false - val resultType = when { - isUsedAsExpression -> inferredType.toIrType() + // Non-exhaustive when can only be used as statement. + expression.isExhaustiveWhen() -> inferredType.toIrType() KotlinBuiltIns.isNothing(inferredType) -> inferredType.toIrType() else -> context.irBuiltIns.unitType } diff --git a/compiler/testData/codegen/box/constants/constantsInWhen.kt b/compiler/testData/codegen/box/constants/constantsInWhen.kt index e19f495e715..cbc39e03146 100644 --- a/compiler/testData/codegen/box/constants/constantsInWhen.kt +++ b/compiler/testData/codegen/box/constants/constantsInWhen.kt @@ -1,7 +1,3 @@ -// Even before any IR lowerings, the type of `when` is determined to be -// Unit even though the outer `if` still returns `Int?`. This results -// in a ClassCastException when that Unit is converted into a Number. -// IGNORE_BACKEND: JVM_IR fun test( b: Boolean, i: Int diff --git a/compiler/testData/ir/irText/expressions/whenUnusedExpression.fir.txt b/compiler/testData/ir/irText/expressions/whenUnusedExpression.fir.txt new file mode 100644 index 00000000000..9dd82178017 --- /dev/null +++ b/compiler/testData/ir/irText/expressions/whenUnusedExpression.fir.txt @@ -0,0 +1,22 @@ +FILE fqName: fileName:/whenUnusedExpression.kt + FUN name:test visibility:public modality:FINAL <> (b:kotlin.Boolean, i:kotlin.Int) returnType:kotlin.Unit + VALUE_PARAMETER name:b index:0 type:kotlin.Boolean + VALUE_PARAMETER name:i index:1 type:kotlin.Int + BLOCK_BODY + WHEN type=kotlin.Unit origin=IF + BRANCH + if: GET_VAR 'b: kotlin.Boolean declared in .test' type=kotlin.Boolean origin=null + then: BLOCK type=kotlin.Unit origin=WHEN + VAR IR_TEMPORARY_VARIABLE name:tmp0_subject type:kotlin.Int [val] + WHEN type=kotlin.Unit origin=WHEN + BRANCH + if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ + arg0: GET_VAR 'val tmp0_subject: kotlin.Int [val] declared in .test' type=kotlin.Int origin=null + arg1: CONST Int type=kotlin.Unit value=0 + then: CONST Int type=kotlin.Unit value=1 + BRANCH + if: CONST Boolean type=kotlin.Boolean value=true + then: CONST Null type=kotlin.Nothing? value=null + BRANCH + if: CONST Boolean type=kotlin.Boolean value=true + then: CONST Null type=kotlin.Nothing? value=null diff --git a/compiler/testData/ir/irText/expressions/whenUnusedExpression.kt b/compiler/testData/ir/irText/expressions/whenUnusedExpression.kt new file mode 100644 index 00000000000..03c282fbda5 --- /dev/null +++ b/compiler/testData/ir/irText/expressions/whenUnusedExpression.kt @@ -0,0 +1,10 @@ +// WITH_RUNTIME + +fun test(b: Boolean, i: Int) { + if (b) { + when (i) { + 0 -> 1 + else -> null + } + } else null +} \ No newline at end of file diff --git a/compiler/testData/ir/irText/expressions/whenUnusedExpression.txt b/compiler/testData/ir/irText/expressions/whenUnusedExpression.txt new file mode 100644 index 00000000000..4fbb5eb2791 --- /dev/null +++ b/compiler/testData/ir/irText/expressions/whenUnusedExpression.txt @@ -0,0 +1,25 @@ +FILE fqName: fileName:/whenUnusedExpression.kt + FUN name:test visibility:public modality:FINAL <> (b:kotlin.Boolean, i:kotlin.Int) returnType:kotlin.Unit + VALUE_PARAMETER name:b index:0 type:kotlin.Boolean + VALUE_PARAMETER name:i index:1 type:kotlin.Int + BLOCK_BODY + TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit + WHEN type=kotlin.Int? origin=IF + BRANCH + if: GET_VAR 'b: kotlin.Boolean declared in .test' type=kotlin.Boolean origin=null + then: BLOCK type=kotlin.Int? origin=null + BLOCK type=kotlin.Int? origin=WHEN + VAR IR_TEMPORARY_VARIABLE name:tmp0_subject type:kotlin.Int [val] + GET_VAR 'i: kotlin.Int declared in .test' type=kotlin.Int origin=null + WHEN type=kotlin.Int? origin=WHEN + BRANCH + if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ + arg0: GET_VAR 'val tmp0_subject: kotlin.Int [val] declared in .test' type=kotlin.Int origin=null + arg1: CONST Int type=kotlin.Int value=0 + then: CONST Int type=kotlin.Int value=1 + BRANCH + if: CONST Boolean type=kotlin.Boolean value=true + then: CONST Null type=kotlin.Nothing? value=null + BRANCH + if: CONST Boolean type=kotlin.Boolean value=true + then: CONST Null type=kotlin.Nothing? value=null diff --git a/compiler/tests/org/jetbrains/kotlin/ir/IrTextTestCaseGenerated.java b/compiler/tests/org/jetbrains/kotlin/ir/IrTextTestCaseGenerated.java index 360ed26cb1c..156fb1c1223 100644 --- a/compiler/tests/org/jetbrains/kotlin/ir/IrTextTestCaseGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/ir/IrTextTestCaseGenerated.java @@ -1267,6 +1267,11 @@ public class IrTextTestCaseGenerated extends AbstractIrTextTestCase { runTest("compiler/testData/ir/irText/expressions/whenReturn.kt"); } + @TestMetadata("whenUnusedExpression.kt") + public void testWhenUnusedExpression() throws Exception { + runTest("compiler/testData/ir/irText/expressions/whenUnusedExpression.kt"); + } + @TestMetadata("whenWithSubjectVariable.kt") public void testWhenWithSubjectVariable() throws Exception { runTest("compiler/testData/ir/irText/expressions/whenWithSubjectVariable.kt");