From 94fe79578e29ee1f33180d8b6e4d4d003fac898b Mon Sep 17 00:00:00 2001 From: Mikhail Glukhikh Date: Thu, 19 Mar 2020 14:19:43 +0300 Subject: [PATCH] [FIR2IR] Generate unconditional branch in exhaustive whens --- .../kotlin/fir/backend/Fir2IrVisitor.kt | 16 +++++++++++++++- compiler/testData/codegen/box/sealed/objects.kt | 1 - compiler/testData/codegen/box/sealed/simple.kt | 1 - .../box/when/enumOptimization/nullableEnum.kt | 1 - 4 files changed, 15 insertions(+), 4 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 09e209a94b1..1f90227e5d8 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 @@ -504,11 +504,25 @@ class Fir2IrVisitor( whenExpression.typeRef.toIrType(), origin ).apply { + var unconditionalBranchFound = false for (branch in whenExpression.branches) { - if (branch.condition !is FirElseIfTrueCondition || branch.result.statements.isNotEmpty()) { + if (branch.condition !is FirElseIfTrueCondition) { branches += branch.accept(this@Fir2IrVisitor, data) as IrBranch + } else { + unconditionalBranchFound = true + if (branch.result.statements.isNotEmpty()) { + branches += branch.accept(this@Fir2IrVisitor, data) as IrBranch + } } } + if (whenExpression.isExhaustive && !unconditionalBranchFound) { + val irResult = IrCallImpl( + startOffset, endOffset, irBuiltIns.nothingType, irBuiltIns.noWhenBranchMatchedExceptionSymbol + ) + branches += IrElseBranchImpl( + IrConstImpl.boolean(startOffset, endOffset, irBuiltIns.booleanType, true), irResult + ) + } } if (subjectVariable == null) { irWhen diff --git a/compiler/testData/codegen/box/sealed/objects.kt b/compiler/testData/codegen/box/sealed/objects.kt index 0873aef3d9f..c33a71d498f 100644 --- a/compiler/testData/codegen/box/sealed/objects.kt +++ b/compiler/testData/codegen/box/sealed/objects.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR sealed class Season { object Warm: Season() object Cold: Season() diff --git a/compiler/testData/codegen/box/sealed/simple.kt b/compiler/testData/codegen/box/sealed/simple.kt index e342bbbd968..01ae3af2c95 100644 --- a/compiler/testData/codegen/box/sealed/simple.kt +++ b/compiler/testData/codegen/box/sealed/simple.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR sealed class Season { class Warm: Season() class Cold: Season() diff --git a/compiler/testData/codegen/box/when/enumOptimization/nullableEnum.kt b/compiler/testData/codegen/box/when/enumOptimization/nullableEnum.kt index 1554e319646..20d5f740782 100644 --- a/compiler/testData/codegen/box/when/enumOptimization/nullableEnum.kt +++ b/compiler/testData/codegen/box/when/enumOptimization/nullableEnum.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR // CHECK_CASES_COUNT: function=test count=0 // CHECK_IF_COUNT: function=test count=3