diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java index 99a083d21fb..6ef635706ff 100644 --- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java +++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java @@ -50237,6 +50237,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT runTest("compiler/testData/codegen/box/valueClasses/throwingMFVCReassignments.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal()); } + @Test + @TestMetadata("tryExpressions.kt") + public void testTryExpressions() throws Exception { + runTest("compiler/testData/codegen/box/valueClasses/tryExpressions.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal()); + } + @Test @TestMetadata("visibility.kt") public void testVisibility() throws Exception { diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBytecodeTextTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBytecodeTextTestGenerated.java index 7d4117d4890..c4bd88a01fa 100644 --- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBytecodeTextTestGenerated.java +++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBytecodeTextTestGenerated.java @@ -5824,6 +5824,12 @@ public class FirBytecodeTextTestGenerated extends AbstractFirBytecodeTextTest { public void testRegularClassWithMFVC() throws Exception { runTest("compiler/testData/codegen/bytecodeText/valueClasses/regularClassWithMFVC.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal()); } + + @Test + @TestMetadata("tryExpressions.kt") + public void testTryExpressions() throws Exception { + runTest("compiler/testData/codegen/bytecodeText/valueClasses/tryExpressions.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal()); + } } @Nested diff --git a/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/JvmMultiFieldValueClassLowering.kt b/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/JvmMultiFieldValueClassLowering.kt index eb14bfb5e21..7405f3d406f 100644 --- a/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/JvmMultiFieldValueClassLowering.kt +++ b/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/JvmMultiFieldValueClassLowering.kt @@ -6,6 +6,7 @@ package org.jetbrains.kotlin.backend.jvm.lower import org.jetbrains.kotlin.backend.common.lower.createIrBuilder +import org.jetbrains.kotlin.backend.common.lower.irCatch import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase import org.jetbrains.kotlin.backend.common.pop import org.jetbrains.kotlin.backend.common.push @@ -1002,14 +1003,21 @@ private class JvmMultiFieldValueClassLowering(context: JvmBackendContext) : JvmV } if (expression is IrWhen) { for (branch in expression.branches) { - branch.condition = branch.condition.transform(this@JvmMultiFieldValueClassLowering, null) + branch.condition = branch.condition.transform(lowering, null) branch.result = irBlock { flattenExpressionTo(branch.result, instance) - } + }.unwrap() } +expression return } + if (expression is IrTry) { + expression.tryResult = irBlock { flattenExpressionTo(expression.tryResult, instance) }.unwrap() + expression.catches.replaceAll { irCatch(it.catchParameter, irBlock { flattenExpressionTo(it.result, instance) }.unwrap()) } + expression.finallyExpression = expression.finallyExpression?.transform(lowering, null) + +expression + return + } if (expression is IrConstructorCall) { val constructor = expression.symbol.owner if (constructor.isPrimary && constructor.constructedClass.isMultiFieldValueClass && @@ -1084,6 +1092,16 @@ private class JvmMultiFieldValueClassLowering(context: JvmBackendContext) : JvmV expression.acceptChildren(this, data) // when's are transparent } + override fun visitCatch(aCatch: IrCatch, data: Boolean) { + aCatch.acceptChildren(this, data) // catches are transparent + } + + override fun visitTry(aTry: IrTry, data: Boolean) { + aTry.tryResult.accept(this, data) + aTry.catches.forEach { it.accept(this, data) } + aTry.finallyExpression?.accept(this, false) + } + override fun visitBranch(branch: IrBranch, data: Boolean) { branch.condition.accept(this, true) branch.result.accept(this, data) diff --git a/compiler/testData/codegen/box/valueClasses/tryExpressions.kt b/compiler/testData/codegen/box/valueClasses/tryExpressions.kt new file mode 100644 index 00000000000..7447986239a --- /dev/null +++ b/compiler/testData/codegen/box/valueClasses/tryExpressions.kt @@ -0,0 +1,43 @@ +// CHECK_BYTECODE_LISTING +// WITH_STDLIB +// TARGET_BACKEND: JVM_IR +// WORKS_WHEN_VALUE_CLASS +// LANGUAGE: +ValueClasses + +@JvmInline +value class DPoint(val x: Double, val y: Double) { + init { + require(x != 0.0 && y != 0.0) + } +} + +fun tryOk() = try { + DPoint(1.0, 2.0) +} catch(_: Throwable) { + DPoint(0.0, 3.0) +} finally { + DPoint(4.0, 5.0) +} + +fun tryFail1() = try { + DPoint(0.0, 1.0) +} catch(_: Throwable) { + DPoint(2.0, 3.0) +} finally { + DPoint(4.0, 5.0) +} + +fun tryFail2() = try { + DPoint(1.0, 2.0) +} catch(_: Throwable) { + DPoint(3.0, 4.0) +} finally { + DPoint(5.0, 0.0) +} + +fun box(): String { + require(runCatching { tryOk() } == Result.success(DPoint(1.0, 2.0))) + require(runCatching { tryFail1() } == Result.success(DPoint(2.0, 3.0))) + require(runCatching { tryFail2() }.isFailure) + return "OK" +} diff --git a/compiler/testData/codegen/box/valueClasses/tryExpressions.txt b/compiler/testData/codegen/box/valueClasses/tryExpressions.txt new file mode 100644 index 00000000000..f21ff8086d3 --- /dev/null +++ b/compiler/testData/codegen/box/valueClasses/tryExpressions.txt @@ -0,0 +1,31 @@ +@kotlin.jvm.JvmInline +@kotlin.Metadata +public final class DPoint { + // source: 'tryExpressions.kt' + private final field field-0: double + private final field field-1: double + private synthetic method (p0: double, p1: double): void + public synthetic final static method box-impl(p0: double, p1: double): DPoint + public final static method constructor-impl(p0: double, p1: double): void + public method equals(@org.jetbrains.annotations.Nullable p0: java.lang.Object): boolean + public static method equals-impl(p0: double, p1: double, p2: java.lang.Object): boolean + public final static method equals-impl0(p0: double, p1: double, p2: double, p3: double): boolean + public final static method getX-impl(p0: double, p1: double): double + public final static method getY-impl(p0: double, p1: double): double + public method hashCode(): int + public static method hashCode-impl(p0: double, p1: double): int + public @org.jetbrains.annotations.NotNull method toString(): java.lang.String + public static method toString-impl(p0: double, p1: double): java.lang.String + public synthetic final method unbox-impl-0(): double + public synthetic final method unbox-impl-1(): double +} + +@kotlin.Metadata +public final class TryExpressionsKt { + // source: 'tryExpressions.kt' + public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String + public final static @org.jetbrains.annotations.NotNull method tryFail1(): DPoint + public final static @org.jetbrains.annotations.NotNull method tryFail2(): DPoint + public final static @org.jetbrains.annotations.NotNull method tryOk(): DPoint + public final inner class kotlin/Result$Companion +} diff --git a/compiler/testData/codegen/bytecodeText/valueClasses/tryExpressions.kt b/compiler/testData/codegen/bytecodeText/valueClasses/tryExpressions.kt new file mode 100644 index 00000000000..dca322fc7a7 --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/valueClasses/tryExpressions.kt @@ -0,0 +1,38 @@ +// CHECK_BYTECODE_LISTING +// WITH_STDLIB +// TARGET_BACKEND: JVM_IR +// WORKS_WHEN_VALUE_CLASS +// LANGUAGE: +ValueClasses + +@JvmInline +value class DPoint(val x: Double, val y: Double) + +fun tryExpr() = try { + DPoint(0.0, 1.0) +} catch(_: Throwable) { + DPoint(2.0, 3.0) +} finally { + DPoint(4.0, 5.0) +} + +fun tryBody() { + try { + DPoint(0.0, 1.0) + } catch(_: Throwable) { + DPoint(2.0, 3.0) + } finally { + DPoint(4.0, 5.0) + } + val x: DPoint = try { + DPoint(0.0, 1.0) + } catch(_: Throwable) { + DPoint(2.0, 3.0) + } finally { + DPoint(4.0, 5.0) + } +} + + +// 1 tryExpr.*(\n .*)(\n .*)*(\n .*box-impl.*)(\n .*)*(\n .*box-impl.*) +// 0 tryExpr.*(\n .*)(\n .*)*(\n .*box-impl.*)(\n .*)*(\n .*box-impl.*)(\n .*)*(\n .*box-impl.*) +// 0 tryBody.*(\n .*)*(\n .*box-impl.*) diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java index 30adab19032..049772afd6d 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java @@ -50237,6 +50237,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/valueClasses/throwingMFVCReassignments.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal()); } + @Test + @TestMetadata("tryExpressions.kt") + public void testTryExpressions() throws Exception { + runTest("compiler/testData/codegen/box/valueClasses/tryExpressions.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal()); + } + @Test @TestMetadata("visibility.kt") public void testVisibility() throws Exception { diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBytecodeTextTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBytecodeTextTestGenerated.java index 001129cd144..8050b901bc0 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBytecodeTextTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBytecodeTextTestGenerated.java @@ -5824,6 +5824,12 @@ public class IrBytecodeTextTestGenerated extends AbstractIrBytecodeTextTest { public void testRegularClassWithMFVC() throws Exception { runTest("compiler/testData/codegen/bytecodeText/valueClasses/regularClassWithMFVC.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal()); } + + @Test + @TestMetadata("tryExpressions.kt") + public void testTryExpressions() throws Exception { + runTest("compiler/testData/codegen/bytecodeText/valueClasses/tryExpressions.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal()); + } } @Nested