diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/SingleAbstractMethodLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/SingleAbstractMethodLowering.kt index 5966c0f3ca7..60b053e97d5 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/SingleAbstractMethodLowering.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/SingleAbstractMethodLowering.kt @@ -28,6 +28,7 @@ import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.ir.declarations.IrFunction import org.jetbrains.kotlin.ir.expressions.IrExpression +import org.jetbrains.kotlin.ir.expressions.IrGetValue import org.jetbrains.kotlin.ir.expressions.IrTypeOperator import org.jetbrains.kotlin.ir.expressions.IrTypeOperatorCall import org.jetbrains.kotlin.ir.expressions.impl.IrInstanceInitializerCallImpl @@ -120,6 +121,15 @@ class SingleAbstractMethodLowering(val context: CommonBackendContext) : FileLowe } +irIfNull(superType, irGet(invokableVariable), irNull(), instance) } + } else if (invokable !is IrGetValue) { + // Hack for the JVM inliner: since the SAM wrappers might be regenerated, avoid putting complex logic + // between the creation of the wrapper and the call of its ``. `MethodInliner` tends to break + // otherwise, e.g. if the argument constructs an anonymous object, resulting in new-new--. + // (See KT-21781 for a similar problem with anonymous object constructor arguments.) + irBlock(invokable, null, superType) { + val invokableVariable = irTemporary(invokable) + +irCall(implementation.constructors.single()).apply { putValueArgument(0, irGet(invokableVariable)) } + } } else { irCall(implementation.constructors.single()).apply { putValueArgument(0, invokable) } } diff --git a/compiler/testData/codegen/boxInline/anonymousObject/sam/anonymousObjectToSam.kt b/compiler/testData/codegen/boxInline/anonymousObject/sam/anonymousObjectToSam.kt new file mode 100644 index 00000000000..fcb940529d3 --- /dev/null +++ b/compiler/testData/codegen/boxInline/anonymousObject/sam/anonymousObjectToSam.kt @@ -0,0 +1,16 @@ +// IGNORE_BACKEND: JVM_IR +// FILE: 1.kt +package test + +inline fun f(crossinline g: () -> Unit) = Runnable(object : () -> Unit { + override fun invoke() = g() +}) + +// FILE: 2.kt +import test.* + +fun box(): String { + var result = "FAIL" + f { result = "OK" }.run() + return result +} diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxInlineCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxInlineCodegenTestGenerated.java index da07ed70afc..eb4d411046c 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxInlineCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxInlineCodegenTestGenerated.java @@ -432,6 +432,11 @@ public class BlackBoxInlineCodegenTestGenerated extends AbstractBlackBoxInlineCo KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/boxInline/anonymousObject/sam"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true); } + @TestMetadata("anonymousObjectToSam.kt") + public void testAnonymousObjectToSam() throws Exception { + runTest("compiler/testData/codegen/boxInline/anonymousObject/sam/anonymousObjectToSam.kt"); + } + @TestMetadata("kt17091.kt") public void testKt17091() throws Exception { runTest("compiler/testData/codegen/boxInline/anonymousObject/sam/kt17091.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/CompileKotlinAgainstInlineKotlinTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/CompileKotlinAgainstInlineKotlinTestGenerated.java index a4d769d538d..ebcb5cbcb80 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/CompileKotlinAgainstInlineKotlinTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/CompileKotlinAgainstInlineKotlinTestGenerated.java @@ -432,6 +432,11 @@ public class CompileKotlinAgainstInlineKotlinTestGenerated extends AbstractCompi KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/boxInline/anonymousObject/sam"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true); } + @TestMetadata("anonymousObjectToSam.kt") + public void testAnonymousObjectToSam() throws Exception { + runTest("compiler/testData/codegen/boxInline/anonymousObject/sam/anonymousObjectToSam.kt"); + } + @TestMetadata("kt17091.kt") public void testKt17091() throws Exception { runTest("compiler/testData/codegen/boxInline/anonymousObject/sam/kt17091.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxInlineCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxInlineCodegenTestGenerated.java index 8bb52efc1ba..9d6106b28aa 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxInlineCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxInlineCodegenTestGenerated.java @@ -432,6 +432,11 @@ public class IrBlackBoxInlineCodegenTestGenerated extends AbstractIrBlackBoxInli KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/boxInline/anonymousObject/sam"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM_IR, true); } + @TestMetadata("anonymousObjectToSam.kt") + public void testAnonymousObjectToSam() throws Exception { + runTest("compiler/testData/codegen/boxInline/anonymousObject/sam/anonymousObjectToSam.kt"); + } + @TestMetadata("kt17091.kt") public void testKt17091() throws Exception { runTest("compiler/testData/codegen/boxInline/anonymousObject/sam/kt17091.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrCompileKotlinAgainstInlineKotlinTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrCompileKotlinAgainstInlineKotlinTestGenerated.java index 6a215d2143c..c355e776ee2 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrCompileKotlinAgainstInlineKotlinTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrCompileKotlinAgainstInlineKotlinTestGenerated.java @@ -432,6 +432,11 @@ public class IrCompileKotlinAgainstInlineKotlinTestGenerated extends AbstractIrC KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/boxInline/anonymousObject/sam"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM_IR, true); } + @TestMetadata("anonymousObjectToSam.kt") + public void testAnonymousObjectToSam() throws Exception { + runTest("compiler/testData/codegen/boxInline/anonymousObject/sam/anonymousObjectToSam.kt"); + } + @TestMetadata("kt17091.kt") public void testKt17091() throws Exception { runTest("compiler/testData/codegen/boxInline/anonymousObject/sam/kt17091.kt");