From a6dae0b37bd6f5c5fb75813eb85188b872eedabe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Steven=20Sch=C3=A4fer?= Date: Thu, 11 Nov 2021 13:47:26 +0100 Subject: [PATCH] JVM IR: Fix value class mangling in SAM wrappers from different modules KT-49659 --- .../FirBlackBoxCodegenTestGenerated.java | 6 ++++++ .../jetbrains/kotlin/backend/jvm/JvmLower.kt | 2 +- .../jvm/lower/JvmInlineClassLowering.kt | 3 ++- .../lower/JvmSingleAbstractMethodLowering.kt | 5 +++-- .../jvm/MemoizedInlineClassReplacements.kt | 4 ++-- .../samWrapperDifferentModule.kt | 20 +++++++++++++++++++ .../codegen/BlackBoxCodegenTestGenerated.java | 6 ++++++ .../IrBlackBoxCodegenTestGenerated.java | 6 ++++++ .../LightAnalysisModeTestGenerated.java | 5 +++++ .../js/test/JsCodegenBoxTestGenerated.java | 6 ++++++ .../test/ir/IrJsCodegenBoxTestGenerated.java | 6 ++++++ .../IrCodegenBoxWasmTestGenerated.java | 5 +++++ 12 files changed, 68 insertions(+), 6 deletions(-) create mode 100644 compiler/testData/codegen/box/inlineClasses/samWrapperDifferentModule.kt 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 b09724fc287..e26c4520346 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 @@ -19788,6 +19788,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT runTest("compiler/testData/codegen/box/inlineClasses/safeAsOfTypeParameterWithInlineClassBound.kt"); } + @Test + @TestMetadata("samWrapperDifferentModule.kt") + public void testSamWrapperDifferentModule() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/samWrapperDifferentModule.kt"); + } + @Test @TestMetadata("secondaryConstructorWithVararg.kt") public void testSecondaryConstructorWithVararg() throws Exception { diff --git a/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/JvmLower.kt b/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/JvmLower.kt index 657abc94d0d..55cb90a6837 100644 --- a/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/JvmLower.kt +++ b/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/JvmLower.kt @@ -353,6 +353,7 @@ private val jvmFilePhases = listOf( rangeContainsLoweringPhase, forLoopsPhase, collectionStubMethodLowering, + singleAbstractMethodPhase, jvmInlineClassPhase, tailrecPhase, makePatchParentsPhase(1), @@ -360,7 +361,6 @@ private val jvmFilePhases = listOf( enumWhenPhase, singletonReferencesPhase, - singleAbstractMethodPhase, assertionPhase, returnableBlocksPhase, sharedVariablesPhase, diff --git a/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/JvmInlineClassLowering.kt b/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/JvmInlineClassLowering.kt index 802dcff8bae..b099dc0d543 100644 --- a/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/JvmInlineClassLowering.kt +++ b/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/JvmInlineClassLowering.kt @@ -47,7 +47,8 @@ val jvmInlineClassPhase = makeIrFilePhase( // forLoopsPhase may produce UInt and ULong which are inline classes. // Standard library replacements are done on the unmangled names for UInt and ULong classes. // Collection stubs may require mangling by inline class rules. - prerequisite = setOf(forLoopsPhase, jvmBuiltInsPhase, collectionStubMethodLowering) + // SAM wrappers may require mangling for fun interfaces with inline class parameters + prerequisite = setOf(forLoopsPhase, jvmBuiltInsPhase, collectionStubMethodLowering, singleAbstractMethodPhase), ) /** diff --git a/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/JvmSingleAbstractMethodLowering.kt b/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/JvmSingleAbstractMethodLowering.kt index 7ff377c5757..1a7b72dff3c 100644 --- a/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/JvmSingleAbstractMethodLowering.kt +++ b/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/JvmSingleAbstractMethodLowering.kt @@ -19,7 +19,6 @@ import org.jetbrains.kotlin.ir.builders.declarations.IrFunctionBuilder import org.jetbrains.kotlin.ir.declarations.IrClass import org.jetbrains.kotlin.ir.declarations.IrDeclaration import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin -import org.jetbrains.kotlin.ir.declarations.IrFunction import org.jetbrains.kotlin.ir.expressions.IrTypeOperatorCall import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.types.getClass @@ -29,7 +28,9 @@ import org.jetbrains.kotlin.utils.addToStdlib.safeAs internal val singleAbstractMethodPhase = makeIrFilePhase( ::JvmSingleAbstractMethodLowering, name = "SingleAbstractMethod", - description = "Replace SAM conversions with instances of interface-implementing classes" + description = "Replace SAM conversions with instances of interface-implementing classes", + // FunctionReferenceLowering produces optimized SAM wrappers. + prerequisite = setOf(functionReferencePhase), ) private class JvmSingleAbstractMethodLowering(context: JvmBackendContext) : SingleAbstractMethodLowering(context) { diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/MemoizedInlineClassReplacements.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/MemoizedInlineClassReplacements.kt index 33a81c4dbfc..a9051951bf4 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/MemoizedInlineClassReplacements.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/MemoizedInlineClassReplacements.kt @@ -54,11 +54,11 @@ class MemoizedInlineClassReplacements( val getReplacementFunction: (IrFunction) -> IrSimpleFunction? = storageManager.createMemoizedFunctionWithNullableValues { when { - // Don't mangle anonymous or synthetic functions + // Don't mangle anonymous or synthetic functions, except for generated SAM wrapper methods (it.isLocal && it is IrSimpleFunction && it.overriddenSymbols.isEmpty()) || (it.origin == IrDeclarationOrigin.DELEGATED_PROPERTY_ACCESSOR && it.visibility == DescriptorVisibilities.LOCAL) || it.isStaticInlineClassReplacement || - it.origin.isSynthetic -> + it.origin.isSynthetic && it.origin != IrDeclarationOrigin.SYNTHETIC_GENERATED_SAM_IMPLEMENTATION -> null it.isInlineClassFieldGetter -> diff --git a/compiler/testData/codegen/box/inlineClasses/samWrapperDifferentModule.kt b/compiler/testData/codegen/box/inlineClasses/samWrapperDifferentModule.kt new file mode 100644 index 00000000000..e53ef8453dd --- /dev/null +++ b/compiler/testData/codegen/box/inlineClasses/samWrapperDifferentModule.kt @@ -0,0 +1,20 @@ +// See KT-49659 +// WITH_RUNTIME +// MODULE: lib +// FILE: lib.kt +@Suppress("OPTIONAL_DECLARATION_USAGE_IN_NON_COMMON_SOURCE") +@kotlin.jvm.JvmInline +value class A(val value: String) + +fun interface B { + fun f(a: A): String +} + +// MODULE: main(lib) +// FILE: test.kt +fun get(b: B) = b.f(A("OK")) + +fun box(): String { + val l = { a: A -> a.value } + return get(l) +} diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java index 1d11c811c5b..fb6832d5002 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java @@ -19626,6 +19626,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/inlineClasses/safeAsOfTypeParameterWithInlineClassBound.kt"); } + @Test + @TestMetadata("samWrapperDifferentModule.kt") + public void testSamWrapperDifferentModule() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/samWrapperDifferentModule.kt"); + } + @Test @TestMetadata("secondaryConstructorWithVararg.kt") public void testSecondaryConstructorWithVararg() throws Exception { 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 e54969742fa..4dc59b89b97 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 @@ -19788,6 +19788,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/inlineClasses/safeAsOfTypeParameterWithInlineClassBound.kt"); } + @Test + @TestMetadata("samWrapperDifferentModule.kt") + public void testSamWrapperDifferentModule() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/samWrapperDifferentModule.kt"); + } + @Test @TestMetadata("secondaryConstructorWithVararg.kt") public void testSecondaryConstructorWithVararg() throws Exception { diff --git a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index 79aafcaa2b6..eeb2311ab1f 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -16298,6 +16298,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTest("compiler/testData/codegen/box/inlineClasses/resultRunCatchingOrElse.kt"); } + @TestMetadata("samWrapperDifferentModule.kt") + public void testSamWrapperDifferentModule() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/samWrapperDifferentModule.kt"); + } + @TestMetadata("secondaryConstructorWithVararg.kt") public void testSecondaryConstructorWithVararg() throws Exception { runTest("compiler/testData/codegen/box/inlineClasses/secondaryConstructorWithVararg.kt"); diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/JsCodegenBoxTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/JsCodegenBoxTestGenerated.java index f5c55da5dac..f26278ccda6 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/JsCodegenBoxTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/JsCodegenBoxTestGenerated.java @@ -15500,6 +15500,12 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { runTest("compiler/testData/codegen/box/inlineClasses/safeAsOfTypeParameterWithInlineClassBound.kt"); } + @Test + @TestMetadata("samWrapperDifferentModule.kt") + public void testSamWrapperDifferentModule() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/samWrapperDifferentModule.kt"); + } + @Test @TestMetadata("secondaryConstructorWithVararg.kt") public void testSecondaryConstructorWithVararg() throws Exception { diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrJsCodegenBoxTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrJsCodegenBoxTestGenerated.java index 04812fcd09f..fc6ae0570c6 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrJsCodegenBoxTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrJsCodegenBoxTestGenerated.java @@ -15464,6 +15464,12 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest { runTest("compiler/testData/codegen/box/inlineClasses/safeAsOfTypeParameterWithInlineClassBound.kt"); } + @Test + @TestMetadata("samWrapperDifferentModule.kt") + public void testSamWrapperDifferentModule() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/samWrapperDifferentModule.kt"); + } + @Test @TestMetadata("secondaryConstructorWithVararg.kt") public void testSecondaryConstructorWithVararg() throws Exception { diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/testOld/wasm/semantics/IrCodegenBoxWasmTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/testOld/wasm/semantics/IrCodegenBoxWasmTestGenerated.java index 924765556d4..2d8c336a814 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/testOld/wasm/semantics/IrCodegenBoxWasmTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/testOld/wasm/semantics/IrCodegenBoxWasmTestGenerated.java @@ -12949,6 +12949,11 @@ public class IrCodegenBoxWasmTestGenerated extends AbstractIrCodegenBoxWasmTest runTest("compiler/testData/codegen/box/inlineClasses/safeAsOfTypeParameterWithInlineClassBound.kt"); } + @TestMetadata("samWrapperDifferentModule.kt") + public void testSamWrapperDifferentModule() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/samWrapperDifferentModule.kt"); + } + @TestMetadata("secondaryConstructorWithVararg.kt") public void testSecondaryConstructorWithVararg() throws Exception { runTest("compiler/testData/codegen/box/inlineClasses/secondaryConstructorWithVararg.kt");