From c072448d22ba0ea20a2aabc65a0c6b7887680e9a Mon Sep 17 00:00:00 2001 From: Ilmir Usmanov Date: Mon, 21 Feb 2022 02:29:16 +0100 Subject: [PATCH] Lower fun interface children's body during inline class lowering #KT-51121 Fixed --- .../FirBlackBoxCodegenTestGenerated.java | 12 ++++++++++ .../jvm/lower/JvmInlineClassLowering.kt | 23 +++++++++++++++---- .../kotlin/backend/jvm/InlineClassAbi.kt | 15 +++++++----- .../box/inlineClasses/funInterface/kt51121.kt | 19 +++++++++++++++ .../inlineClasses/funInterface/kt51121_2.kt | 20 ++++++++++++++++ .../codegen/BlackBoxCodegenTestGenerated.java | 12 ++++++++++ .../IrBlackBoxCodegenTestGenerated.java | 12 ++++++++++ .../LightAnalysisModeTestGenerated.java | 10 ++++++++ .../js/test/JsCodegenBoxTestGenerated.java | 12 ++++++++++ .../test/ir/IrJsCodegenBoxTestGenerated.java | 12 ++++++++++ .../IrCodegenBoxWasmTestGenerated.java | 10 ++++++++ .../NativeCodegenBoxTestGenerated.java | 16 +++++++++++++ 12 files changed, 163 insertions(+), 10 deletions(-) create mode 100644 compiler/testData/codegen/box/inlineClasses/funInterface/kt51121.kt create mode 100644 compiler/testData/codegen/box/inlineClasses/funInterface/kt51121_2.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 e095b94d509..f8c4e428add 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 @@ -23200,6 +23200,18 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT runTest("compiler/testData/codegen/box/inlineClasses/funInterface/javaSamReturnResult.kt"); } + @Test + @TestMetadata("kt51121.kt") + public void testKt51121() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/funInterface/kt51121.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal()); + } + + @Test + @TestMetadata("kt51121_2.kt") + public void testKt51121_2() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/funInterface/kt51121_2.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal()); + } + @Test @TestMetadata("mangledSamWrappers.kt") public void testMangledSamWrappers() throws Exception { 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 3f25a4b806f..12ccc5ebaaf 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 @@ -122,10 +122,14 @@ private class JvmInlineClassLowering(private val context: JvmBackendContext) : F return null } - // If fun interface methods are already mangled, do not mangle them twice. - if (function is IrSimpleFunction && function.overriddenSymbols.any { it.owner.parentAsClass.isFun } && - function.name.asString().substringAfterLast('-') == replacement.name.asString().substringAfterLast('-') - ) return null + if (function is IrSimpleFunction && function.overriddenSymbols.any { it.owner.parentAsClass.isFun }) { + // If fun interface methods are already mangled, do not mangle them twice. + val suffix = function.hashSuffix() + if (suffix != null && function.name.asString().endsWith(suffix)) { + function.transformChildrenVoid() + return null + } + } addBindingsFor(function, replacement) return when (function) { @@ -135,6 +139,13 @@ private class JvmInlineClassLowering(private val context: JvmBackendContext) : F } } + private fun IrFunction.hashSuffix(): String? = + InlineClassAbi.hashSuffix( + this, + context.state.functionsWithInlineClassReturnTypesMangled, + context.state.useOldManglingSchemeForFunctionsWithInlineClassesInSignatures + ) + private fun transformSimpleFunctionFlat(function: IrSimpleFunction, replacement: IrSimpleFunction): List { replacement.valueParameters.forEach { it.transformChildrenVoid() @@ -460,6 +471,10 @@ private class JvmInlineClassLowering(private val context: JvmBackendContext) : F override fun visitReturn(expression: IrReturn): IrExpression { expression.returnTargetSymbol.owner.safeAs()?.let { target -> + val suffix = target.hashSuffix() + if (suffix != null && target.name.asString().endsWith(suffix)) + return super.visitReturn(expression) + context.inlineClassReplacements.getReplacementFunction(target)?.let { return context.createIrBuilder(it.symbol, expression.startOffset, expression.endOffset).irReturn( expression.value.transform(this, null) diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/InlineClassAbi.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/InlineClassAbi.kt index b83f2627241..6a251ee3959 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/InlineClassAbi.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/InlineClassAbi.kt @@ -66,12 +66,7 @@ object InlineClassAbi { return Name.identifier("constructor-impl") } - val suffix = hashSuffix( - useOldMangleRules, - irFunction.fullValueParameterList.map { it.type }, - irFunction.returnType.takeIf { mangleReturnTypes && irFunction.hasMangledReturnType }, - irFunction.isSuspend - ) + val suffix = hashSuffix(irFunction, mangleReturnTypes, useOldMangleRules) if (suffix == null && ((irFunction.parent as? IrClass)?.isSingleFieldValueClass != true || irFunction.origin == IrDeclarationOrigin.IR_BUILTINS_STUB)) { return irFunction.name } @@ -90,6 +85,14 @@ object InlineClassAbi { return Name.identifier("$base-${suffix ?: "impl"}") } + fun hashSuffix(irFunction: IrFunction, mangleReturnTypes: Boolean, useOldMangleRules: Boolean): String? = + hashSuffix( + useOldMangleRules, + irFunction.fullValueParameterList.map { it.type }, + irFunction.returnType.takeIf { mangleReturnTypes && irFunction.hasMangledReturnType }, + irFunction.isSuspend + ) + fun hashSuffix( useOldMangleRules: Boolean, valueParameters: List, diff --git a/compiler/testData/codegen/box/inlineClasses/funInterface/kt51121.kt b/compiler/testData/codegen/box/inlineClasses/funInterface/kt51121.kt new file mode 100644 index 00000000000..55723e8a6e7 --- /dev/null +++ b/compiler/testData/codegen/box/inlineClasses/funInterface/kt51121.kt @@ -0,0 +1,19 @@ +// WITH_STDLIB +// WORKS_WHEN_VALUE_CLASS +// LANGUAGE: +ValueClasses +// IGNORE_BACKEND: JVM +// FILE: 1.kt + +fun interface F { + fun foo(s: String): Z +} + +OPTIONAL_JVM_INLINE_ANNOTATION +value class Z(val value: String) + +// FILE: 2.kt + +val f: F = F { value -> Z(value) } + +fun box(): String = + f.foo("OK").value diff --git a/compiler/testData/codegen/box/inlineClasses/funInterface/kt51121_2.kt b/compiler/testData/codegen/box/inlineClasses/funInterface/kt51121_2.kt new file mode 100644 index 00000000000..fe6289082c7 --- /dev/null +++ b/compiler/testData/codegen/box/inlineClasses/funInterface/kt51121_2.kt @@ -0,0 +1,20 @@ +// WITH_STDLIB +// WORKS_WHEN_VALUE_CLASS +// LANGUAGE: +ValueClasses +// IGNORE_BACKEND: JVM +// FILE: 1.kt + +val f: F = F { value -> Z(value) } + +fun box(): String = + f.foo("OK").value + +// FILE: 2.kt + +fun interface F { + fun foo(s: String): Z +} + +OPTIONAL_JVM_INLINE_ANNOTATION +value class Z(val value: String) + 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 49b8c80d017..7eb467031c6 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 @@ -22762,6 +22762,18 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/inlineClasses/funInterface/javaSamReturnResult.kt"); } + @Test + @TestMetadata("kt51121.kt") + public void testKt51121() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/funInterface/kt51121.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal()); + } + + @Test + @TestMetadata("kt51121_2.kt") + public void testKt51121_2() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/funInterface/kt51121_2.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal()); + } + @Test @TestMetadata("mangledSamWrappers.kt") public void testMangledSamWrappers() 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 d736dc7c2b5..f333ac2adde 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 @@ -23200,6 +23200,18 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/inlineClasses/funInterface/javaSamReturnResult.kt"); } + @Test + @TestMetadata("kt51121.kt") + public void testKt51121() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/funInterface/kt51121.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal()); + } + + @Test + @TestMetadata("kt51121_2.kt") + public void testKt51121_2() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/funInterface/kt51121_2.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal()); + } + @Test @TestMetadata("mangledSamWrappers.kt") public void testMangledSamWrappers() 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 8aa01be055f..c5bfe1b83ee 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -18993,6 +18993,16 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTest("compiler/testData/codegen/box/inlineClasses/funInterface/argumentResult.kt"); } + @TestMetadata("kt51121.kt") + public void ignoreKt51121() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/funInterface/kt51121.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal()); + } + + @TestMetadata("kt51121_2.kt") + public void ignoreKt51121_2() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/funInterface/kt51121_2.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal()); + } + @TestMetadata("mangledSamWrappers.kt") public void ignoreMangledSamWrappers() throws Exception { runTest("compiler/testData/codegen/box/inlineClasses/funInterface/mangledSamWrappers.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal()); 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 615f1576d0c..28b0334a45c 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 @@ -18198,6 +18198,18 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { runTest("compiler/testData/codegen/box/inlineClasses/funInterface/argumentResult.kt"); } + @Test + @TestMetadata("kt51121.kt") + public void testKt51121() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/funInterface/kt51121.kt", TransformersFunctions.getRemoveOptionalJvmInlineAnnotation()); + } + + @Test + @TestMetadata("kt51121_2.kt") + public void testKt51121_2() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/funInterface/kt51121_2.kt", TransformersFunctions.getRemoveOptionalJvmInlineAnnotation()); + } + @Test @TestMetadata("mangledSamWrappers.kt") public void testMangledSamWrappers() 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 12ad9b5aed8..df245476de4 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 @@ -18162,6 +18162,18 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest { runTest("compiler/testData/codegen/box/inlineClasses/funInterface/argumentResult.kt"); } + @Test + @TestMetadata("kt51121.kt") + public void testKt51121() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/funInterface/kt51121.kt", TransformersFunctions.getRemoveOptionalJvmInlineAnnotation()); + } + + @Test + @TestMetadata("kt51121_2.kt") + public void testKt51121_2() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/funInterface/kt51121_2.kt", TransformersFunctions.getRemoveOptionalJvmInlineAnnotation()); + } + @Test @TestMetadata("mangledSamWrappers.kt") public void testMangledSamWrappers() 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 0397d8fb875..3c2c3b20fed 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 @@ -15354,6 +15354,16 @@ public class IrCodegenBoxWasmTestGenerated extends AbstractIrCodegenBoxWasmTest runTest("compiler/testData/codegen/box/inlineClasses/funInterface/argumentResult.kt"); } + @TestMetadata("kt51121.kt") + public void testKt51121() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/funInterface/kt51121.kt", TransformersFunctions.getRemoveOptionalJvmInlineAnnotation()); + } + + @TestMetadata("kt51121_2.kt") + public void testKt51121_2() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/funInterface/kt51121_2.kt", TransformersFunctions.getRemoveOptionalJvmInlineAnnotation()); + } + @TestMetadata("mangledSamWrappers.kt") public void testMangledSamWrappers() throws Exception { runTest("compiler/testData/codegen/box/inlineClasses/funInterface/mangledSamWrappers.kt", TransformersFunctions.getRemoveOptionalJvmInlineAnnotation()); diff --git a/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/NativeCodegenBoxTestGenerated.java b/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/NativeCodegenBoxTestGenerated.java index c3f291bbcaa..a9bf9ae7c4a 100644 --- a/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/NativeCodegenBoxTestGenerated.java +++ b/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/NativeCodegenBoxTestGenerated.java @@ -20269,6 +20269,8 @@ public class NativeCodegenBoxTestGenerated extends AbstractNativeCodegenBoxTest public FunInterface() { register("compiler/testData/codegen/box/inlineClasses/funInterface/argumentIC.kt", TransformersFunctions.getRemoveOptionalJvmInlineAnnotation()); register("compiler/testData/codegen/box/inlineClasses/funInterface/argumentICGeneric.kt", TransformersFunctions.getRemoveOptionalJvmInlineAnnotation()); + register("compiler/testData/codegen/box/inlineClasses/funInterface/kt51121.kt", TransformersFunctions.getRemoveOptionalJvmInlineAnnotation()); + register("compiler/testData/codegen/box/inlineClasses/funInterface/kt51121_2.kt", TransformersFunctions.getRemoveOptionalJvmInlineAnnotation()); register("compiler/testData/codegen/box/inlineClasses/funInterface/mangledSamWrappers.kt", TransformersFunctions.getRemoveOptionalJvmInlineAnnotation()); register("compiler/testData/codegen/box/inlineClasses/funInterface/mangledSamWrappersGeneric.kt", TransformersFunctions.getRemoveOptionalJvmInlineAnnotation()); register("compiler/testData/codegen/box/inlineClasses/funInterface/returnIC.kt", TransformersFunctions.getRemoveOptionalJvmInlineAnnotation()); @@ -20300,6 +20302,20 @@ public class NativeCodegenBoxTestGenerated extends AbstractNativeCodegenBoxTest runTest("compiler/testData/codegen/box/inlineClasses/funInterface/argumentResult.kt"); } + @Test + @TestMetadata("kt51121.kt") + public void testKt51121() throws Exception { + // There is a registered source transformer for the testcase: TransformersFunctions.getRemoveOptionalJvmInlineAnnotation() + runTest("compiler/testData/codegen/box/inlineClasses/funInterface/kt51121.kt"); + } + + @Test + @TestMetadata("kt51121_2.kt") + public void testKt51121_2() throws Exception { + // There is a registered source transformer for the testcase: TransformersFunctions.getRemoveOptionalJvmInlineAnnotation() + runTest("compiler/testData/codegen/box/inlineClasses/funInterface/kt51121_2.kt"); + } + @Test @TestMetadata("mangledSamWrappers.kt") public void testMangledSamWrappers() throws Exception {