From 549ea1a3b9c249dfd5b70879a972c5c445a58f7e Mon Sep 17 00:00:00 2001 From: Ilmir Usmanov Date: Mon, 27 Dec 2021 10:07:39 +0100 Subject: [PATCH] If fun interface methods are already mangled, do not mangle them twice There are two possible scenarios, when fun interface method with inline class parameter can be compiled. First is when we compile fun interface itself before SAM adapter. In that case, fun interface is lowered before we lower SAM adapter. Thus, its method is mangled and mangling in the second time is an error. Second is when we compile SAM adapter before the fun interface. In that case, fun interface is not lowered, and we have to mangle the method. The only way to distinguish there two cases I can think of is to check whether the overridden method is already mangled, in other words, check, whether the overridden method's suffix is doubled. #KT-48499: Fixed --- .../FirBlackBoxCodegenTestGenerated.java | 24 +++++++++++++++++++ .../jvm/lower/JvmInlineClassLowering.kt | 5 ++++ .../inlineClasses/funInterfaceDoubleSuffux.kt | 20 ++++++++++++++++ .../funInterfaceDoubleSuffux2.kt | 20 ++++++++++++++++ .../codegen/BlackBoxCodegenTestGenerated.java | 12 ++++++++++ .../IrBlackBoxCodegenTestGenerated.java | 24 +++++++++++++++++++ .../LightAnalysisModeTestGenerated.java | 10 ++++++++ .../js/test/JsCodegenBoxTestGenerated.java | 12 ++++++++++ .../test/ir/IrJsCodegenBoxTestGenerated.java | 12 ++++++++++ .../IrCodegenBoxWasmTestGenerated.java | 10 ++++++++ .../blackboxtest/ExternalTestGenerated.java | 16 +++++++++++++ 11 files changed, 165 insertions(+) create mode 100644 compiler/testData/codegen/box/inlineClasses/funInterfaceDoubleSuffux.kt create mode 100644 compiler/testData/codegen/box/inlineClasses/funInterfaceDoubleSuffux2.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 4117a4f6a91..9ebecfc0496 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 @@ -20205,6 +20205,30 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT runTest("compiler/testData/codegen/box/inlineClasses/fieldNameClash.kt", TransformersFunctions.getRemoveOptionalJvmInlineAnnotation()); } + @Test + @TestMetadata("funInterfaceDoubleSuffux.kt") + public void testFunInterfaceDoubleSuffux() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/funInterfaceDoubleSuffux.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal()); + } + + @Test + @TestMetadata("funInterfaceDoubleSuffux2.kt") + public void testFunInterfaceDoubleSuffux2() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/funInterfaceDoubleSuffux2.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal()); + } + + @Test + @TestMetadata("funInterfaceDoubleSuffux2.kt") + public void testFunInterfaceDoubleSuffux2_valueClasses() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/funInterfaceDoubleSuffux2.kt", TransformersFunctions.getRemoveOptionalJvmInlineAnnotation()); + } + + @Test + @TestMetadata("funInterfaceDoubleSuffux.kt") + public void testFunInterfaceDoubleSuffux_valueClasses() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/funInterfaceDoubleSuffux.kt", TransformersFunctions.getRemoveOptionalJvmInlineAnnotation()); + } + @Test @TestMetadata("functionExpression.kt") public void testFunctionExpression() 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 b099dc0d543..cc847de6aef 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 @@ -120,6 +120,11 @@ 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 + addBindingsFor(function, replacement) return when (function) { is IrSimpleFunction -> transformSimpleFunctionFlat(function, replacement) diff --git a/compiler/testData/codegen/box/inlineClasses/funInterfaceDoubleSuffux.kt b/compiler/testData/codegen/box/inlineClasses/funInterfaceDoubleSuffux.kt new file mode 100644 index 00000000000..a563033a968 --- /dev/null +++ b/compiler/testData/codegen/box/inlineClasses/funInterfaceDoubleSuffux.kt @@ -0,0 +1,20 @@ +// WITH_STDLIB +// WORKS_WHEN_VALUE_CLASS +// LANGUAGE: +ValueClasses + +// FILE: Kt15AbstractMethodError2.kt + +OPTIONAL_JVM_INLINE_ANNOTATION +value class MyValueClazz(val base: Long) + +fun interface MyInterface { + fun myMethod(x: MyValueClazz) +} + +// FILE: Kt15AbstractMethodErrorRepro.kt + +fun box(): String { + val foo = MyInterface { _ -> } + foo.myMethod(MyValueClazz(0L)) + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/inlineClasses/funInterfaceDoubleSuffux2.kt b/compiler/testData/codegen/box/inlineClasses/funInterfaceDoubleSuffux2.kt new file mode 100644 index 00000000000..183343e522e --- /dev/null +++ b/compiler/testData/codegen/box/inlineClasses/funInterfaceDoubleSuffux2.kt @@ -0,0 +1,20 @@ +// WITH_STDLIB +// WORKS_WHEN_VALUE_CLASS +// LANGUAGE: +ValueClasses + +// FILE: Kt15AbstractMethodErrorRepro.kt + +fun box(): String { + val foo = MyInterface { _ -> } + foo.myMethod(MyValueClazz(0L)) + return "OK" +} + +// FILE: Kt15AbstractMethodError2.kt + +OPTIONAL_JVM_INLINE_ANNOTATION +value class MyValueClazz(val base: Long) + +fun interface MyInterface { + fun myMethod(x: MyValueClazz) +} \ No newline at end of file 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 075f1e0859d..9a7664f9f58 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 @@ -19407,6 +19407,18 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/inlineClasses/fieldNameClash.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal()); } + @Test + @TestMetadata("funInterfaceDoubleSuffux.kt") + public void testFunInterfaceDoubleSuffux() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/funInterfaceDoubleSuffux.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal()); + } + + @Test + @TestMetadata("funInterfaceDoubleSuffux2.kt") + public void testFunInterfaceDoubleSuffux2() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/funInterfaceDoubleSuffux2.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal()); + } + @Test @TestMetadata("functionExpression.kt") public void testFunctionExpression() 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 74b8cf4703f..3ca74b80da3 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 @@ -20205,6 +20205,30 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/inlineClasses/fieldNameClash.kt", TransformersFunctions.getRemoveOptionalJvmInlineAnnotation()); } + @Test + @TestMetadata("funInterfaceDoubleSuffux.kt") + public void testFunInterfaceDoubleSuffux() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/funInterfaceDoubleSuffux.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal()); + } + + @Test + @TestMetadata("funInterfaceDoubleSuffux2.kt") + public void testFunInterfaceDoubleSuffux2() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/funInterfaceDoubleSuffux2.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal()); + } + + @Test + @TestMetadata("funInterfaceDoubleSuffux2.kt") + public void testFunInterfaceDoubleSuffux2_valueClasses() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/funInterfaceDoubleSuffux2.kt", TransformersFunctions.getRemoveOptionalJvmInlineAnnotation()); + } + + @Test + @TestMetadata("funInterfaceDoubleSuffux.kt") + public void testFunInterfaceDoubleSuffux_valueClasses() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/funInterfaceDoubleSuffux.kt", TransformersFunctions.getRemoveOptionalJvmInlineAnnotation()); + } + @Test @TestMetadata("functionExpression.kt") public void testFunctionExpression() 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 138498e34dc..2f454600a07 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -16197,6 +16197,16 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTest("compiler/testData/codegen/box/inlineClasses/fieldNameClash.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal()); } + @TestMetadata("funInterfaceDoubleSuffux.kt") + public void testFunInterfaceDoubleSuffux() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/funInterfaceDoubleSuffux.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal()); + } + + @TestMetadata("funInterfaceDoubleSuffux2.kt") + public void testFunInterfaceDoubleSuffux2() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/funInterfaceDoubleSuffux2.kt", TransformersFunctions.getReplaceOptionalJvmInlineAnnotationWithReal()); + } + @TestMetadata("functionExpression.kt") public void testFunctionExpression() throws Exception { runTest("compiler/testData/codegen/box/inlineClasses/functionExpression.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 84f4dfbc5a1..0938c267ec2 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 @@ -15263,6 +15263,18 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { runTest("compiler/testData/codegen/box/inlineClasses/fieldNameClash.kt", TransformersFunctions.getRemoveOptionalJvmInlineAnnotation()); } + @Test + @TestMetadata("funInterfaceDoubleSuffux.kt") + public void testFunInterfaceDoubleSuffux() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/funInterfaceDoubleSuffux.kt", TransformersFunctions.getRemoveOptionalJvmInlineAnnotation()); + } + + @Test + @TestMetadata("funInterfaceDoubleSuffux2.kt") + public void testFunInterfaceDoubleSuffux2() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/funInterfaceDoubleSuffux2.kt", TransformersFunctions.getRemoveOptionalJvmInlineAnnotation()); + } + @Test @TestMetadata("functionExpression.kt") public void testFunctionExpression() 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 7ca831f0666..66431197a95 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 @@ -15227,6 +15227,18 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest { runTest("compiler/testData/codegen/box/inlineClasses/fieldNameClash.kt", TransformersFunctions.getRemoveOptionalJvmInlineAnnotation()); } + @Test + @TestMetadata("funInterfaceDoubleSuffux.kt") + public void testFunInterfaceDoubleSuffux() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/funInterfaceDoubleSuffux.kt", TransformersFunctions.getRemoveOptionalJvmInlineAnnotation()); + } + + @Test + @TestMetadata("funInterfaceDoubleSuffux2.kt") + public void testFunInterfaceDoubleSuffux2() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/funInterfaceDoubleSuffux2.kt", TransformersFunctions.getRemoveOptionalJvmInlineAnnotation()); + } + @Test @TestMetadata("functionExpression.kt") public void testFunctionExpression() 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 fef1b0b5f88..da5d9dc5b9a 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 @@ -12829,6 +12829,16 @@ public class IrCodegenBoxWasmTestGenerated extends AbstractIrCodegenBoxWasmTest runTest("compiler/testData/codegen/box/inlineClasses/fieldNameClash.kt", TransformersFunctions.getRemoveOptionalJvmInlineAnnotation()); } + @TestMetadata("funInterfaceDoubleSuffux.kt") + public void testFunInterfaceDoubleSuffux() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/funInterfaceDoubleSuffux.kt", TransformersFunctions.getRemoveOptionalJvmInlineAnnotation()); + } + + @TestMetadata("funInterfaceDoubleSuffux2.kt") + public void testFunInterfaceDoubleSuffux2() throws Exception { + runTest("compiler/testData/codegen/box/inlineClasses/funInterfaceDoubleSuffux2.kt", TransformersFunctions.getRemoveOptionalJvmInlineAnnotation()); + } + @TestMetadata("functionExpression.kt") public void testFunctionExpression() throws Exception { runTest("compiler/testData/codegen/box/inlineClasses/functionExpression.kt", TransformersFunctions.getRemoveOptionalJvmInlineAnnotation()); diff --git a/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/ExternalTestGenerated.java b/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/ExternalTestGenerated.java index 48d9b73ca0e..87d1015ae40 100644 --- a/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/ExternalTestGenerated.java +++ b/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/ExternalTestGenerated.java @@ -15993,6 +15993,8 @@ public class ExternalTestGenerated extends AbstractExternalNativeBlackBoxTest { register("compiler/testData/codegen/box/inlineClasses/extLambdaInInlineClassFun.kt", TransformersFunctions.getRemoveOptionalJvmInlineAnnotation()); register("compiler/testData/codegen/box/inlineClasses/extLambdaInInlineClassFun2.kt", TransformersFunctions.getRemoveOptionalJvmInlineAnnotation()); register("compiler/testData/codegen/box/inlineClasses/fieldNameClash.kt", TransformersFunctions.getRemoveOptionalJvmInlineAnnotation()); + register("compiler/testData/codegen/box/inlineClasses/funInterfaceDoubleSuffux.kt", TransformersFunctions.getRemoveOptionalJvmInlineAnnotation()); + register("compiler/testData/codegen/box/inlineClasses/funInterfaceDoubleSuffux2.kt", TransformersFunctions.getRemoveOptionalJvmInlineAnnotation()); register("compiler/testData/codegen/box/inlineClasses/functionExpression.kt", TransformersFunctions.getRemoveOptionalJvmInlineAnnotation()); register("compiler/testData/codegen/box/inlineClasses/genericInlineClassSynthMembers.kt", TransformersFunctions.getRemoveOptionalJvmInlineAnnotation()); register("compiler/testData/codegen/box/inlineClasses/genericVararg2ndConstructor.kt", TransformersFunctions.getRemoveOptionalJvmInlineAnnotation()); @@ -16549,6 +16551,20 @@ public class ExternalTestGenerated extends AbstractExternalNativeBlackBoxTest { runTest("compiler/testData/codegen/box/inlineClasses/fieldNameClash.kt"); } + @Test + @TestMetadata("funInterfaceDoubleSuffux.kt") + public void testFunInterfaceDoubleSuffux() throws Exception { + // There is a registered source transformer for the testcase: TransformersFunctions.getRemoveOptionalJvmInlineAnnotation() + runTest("compiler/testData/codegen/box/inlineClasses/funInterfaceDoubleSuffux.kt"); + } + + @Test + @TestMetadata("funInterfaceDoubleSuffux2.kt") + public void testFunInterfaceDoubleSuffux2() throws Exception { + // There is a registered source transformer for the testcase: TransformersFunctions.getRemoveOptionalJvmInlineAnnotation() + runTest("compiler/testData/codegen/box/inlineClasses/funInterfaceDoubleSuffux2.kt"); + } + @Test @TestMetadata("functionExpression.kt") public void testFunctionExpression() throws Exception {