From 9e9ca4953f40b7d5de32431e92d5d2d0c0a4b9bb Mon Sep 17 00:00:00 2001 From: Jinseong Jeon Date: Tue, 16 Jun 2020 23:23:18 -0700 Subject: [PATCH] FIR2IR: coerce to Unit when "when" expr is not effectively exhaustive --- .../src/org/jetbrains/kotlin/fir/backend/Fir2IrVisitor.kt | 6 +++++- compiler/testData/codegen/box/regressions/kt528.kt | 1 - compiler/testData/codegen/box/regressions/kt529.kt | 1 - compiler/testData/codegen/box/regressions/kt533.kt | 1 - compiler/testData/ir/irText/expressions/ifElseIf.fir.txt | 4 ++-- 5 files changed, 7 insertions(+), 6 deletions(-) diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrVisitor.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrVisitor.kt index 39f60900403..fa8519ea26f 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrVisitor.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrVisitor.kt @@ -581,11 +581,15 @@ class Fir2IrVisitor( KtNodeTypes.POSTFIX_EXPRESSION -> IrStatementOrigin.EXCLEXCL else -> null } + // If the constant true branch has empty body, it won't be converted. Thus, the entire `when` expression is effectively _not_ + // exhaustive anymore. In that case, coerce the return type of `when` expression to Unit as per the backend expectation. + val effectivelyNotExhaustive = !whenExpression.isExhaustive || + whenExpression.branches.any { it.condition is FirElseIfTrueCondition && it.result.statements.isEmpty() } return conversionScope.withWhenSubject(subjectVariable) { whenExpression.convertWithOffsets { startOffset, endOffset -> val irWhen = IrWhenImpl( startOffset, endOffset, - whenExpression.typeRef.toIrType(), + if (effectivelyNotExhaustive) irBuiltIns.unitType else whenExpression.typeRef.toIrType(), origin ).apply { var unconditionalBranchFound = false diff --git a/compiler/testData/codegen/box/regressions/kt528.kt b/compiler/testData/codegen/box/regressions/kt528.kt index 69bd247f7e4..30b7260f257 100644 --- a/compiler/testData/codegen/box/regressions/kt528.kt +++ b/compiler/testData/codegen/box/regressions/kt528.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR // TARGET_BACKEND: JVM // WITH_RUNTIME diff --git a/compiler/testData/codegen/box/regressions/kt529.kt b/compiler/testData/codegen/box/regressions/kt529.kt index d3cc89b47cf..e0cbe3dd126 100644 --- a/compiler/testData/codegen/box/regressions/kt529.kt +++ b/compiler/testData/codegen/box/regressions/kt529.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR // TARGET_BACKEND: JVM // WITH_RUNTIME diff --git a/compiler/testData/codegen/box/regressions/kt533.kt b/compiler/testData/codegen/box/regressions/kt533.kt index 2586265da43..0e3fc2c3301 100644 --- a/compiler/testData/codegen/box/regressions/kt533.kt +++ b/compiler/testData/codegen/box/regressions/kt533.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR // TARGET_BACKEND: JVM // WITH_RUNTIME diff --git a/compiler/testData/ir/irText/expressions/ifElseIf.fir.txt b/compiler/testData/ir/irText/expressions/ifElseIf.fir.txt index 3dd1bb6081a..87d0a700c3f 100644 --- a/compiler/testData/ir/irText/expressions/ifElseIf.fir.txt +++ b/compiler/testData/ir/irText/expressions/ifElseIf.fir.txt @@ -31,7 +31,7 @@ FILE fqName: fileName:/ifElseIf.kt BRANCH if: CONST Boolean type=kotlin.Boolean value=true then: CONST Boolean type=kotlin.Boolean value=true - WHEN type=kotlin.Any origin=IF + WHEN type=kotlin.Unit origin=IF BRANCH if: GET_VAR 'flag: kotlin.Boolean declared in .testEmptyBranches1' type=kotlin.Boolean origin=null then: CONST Boolean type=kotlin.Boolean value=true @@ -45,7 +45,7 @@ FILE fqName: fileName:/ifElseIf.kt BRANCH if: CONST Boolean type=kotlin.Boolean value=true then: CONST Boolean type=kotlin.Boolean value=true - WHEN type=kotlin.Any origin=IF + WHEN type=kotlin.Unit origin=IF BRANCH if: GET_VAR 'flag: kotlin.Boolean declared in .testEmptyBranches2' type=kotlin.Boolean origin=null then: CONST Boolean type=kotlin.Boolean value=true