From 19bbcc586943cb62a55f7b93e4cb256f52ca20fb Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Wed, 31 Aug 2022 23:37:44 +0200 Subject: [PATCH] Do not generate metadata for callable reference classes After an accidental change in 846537b367, we started generating metadata into anonymous classes for callable references. This metadata contained the Kotlin representation of the referenced function. In KT-53794, this led to a problem where Java's protected visibility could not be represented in Kotlin terms, which crashed the backend. But also, this metadata is useless because there's no real use case for interpreting it (since you already have a function reference object at runtime with all the needed information), so it would take some extra space in the bytecode. #KT-53794 Fixed --- .../FirBlackBoxCodegenTestGenerated.java | 6 ++++++ .../codegen/FirBytecodeTextTestGenerated.java | 6 ++++++ .../jvm/lower/FunctionReferenceLowering.kt | 2 +- .../function/kt53794_protectedJavaMember.kt | 18 ++++++++++++++++++ .../callableReference/noMetadata.kt | 9 +++++++++ .../codegen/BlackBoxCodegenTestGenerated.java | 6 ++++++ .../IrBlackBoxCodegenTestGenerated.java | 6 ++++++ .../codegen/IrBytecodeTextTestGenerated.java | 6 ++++++ .../LightAnalysisModeTestGenerated.java | 5 +++++ 9 files changed, 63 insertions(+), 1 deletion(-) create mode 100644 compiler/testData/codegen/box/callableReference/function/kt53794_protectedJavaMember.kt create mode 100644 compiler/testData/codegen/bytecodeText/callableReference/noMetadata.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 a55b02735f2..f4de4deb7ba 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 @@ -4116,6 +4116,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT runTest("compiler/testData/codegen/box/callableReference/function/kt47741.kt"); } + @Test + @TestMetadata("kt53794_protectedJavaMember.kt") + public void testKt53794_protectedJavaMember() throws Exception { + runTest("compiler/testData/codegen/box/callableReference/function/kt53794_protectedJavaMember.kt"); + } + @Test @TestMetadata("nestedConstructorFromClass.kt") public void testNestedConstructorFromClass() 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 f5d041886ce..960a114903e 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 @@ -958,6 +958,12 @@ public class FirBytecodeTextTestGenerated extends AbstractFirBytecodeTextTest { runTest("compiler/testData/codegen/bytecodeText/callableReference/nameIntrinsicWithImplicitThis.kt"); } + @Test + @TestMetadata("noMetadata.kt") + public void testNoMetadata() throws Exception { + runTest("compiler/testData/codegen/bytecodeText/callableReference/noMetadata.kt"); + } + @Test @TestMetadata("unboundFieldReferenceInInline.kt") public void testUnboundFieldReferenceInInline() throws Exception { diff --git a/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/FunctionReferenceLowering.kt b/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/FunctionReferenceLowering.kt index a0412c70f2c..aeea6016a57 100644 --- a/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/FunctionReferenceLowering.kt +++ b/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/FunctionReferenceLowering.kt @@ -545,7 +545,7 @@ internal class FunctionReferenceLowering(private val context: JvmBackendContext) } createImplicitParameterDeclarationWithWrappedDescriptor() copyAttributes(irFunctionReference) - if (!isLightweightLambda) { + if (isHeavyweightLambda) { metadata = irFunctionReference.symbol.owner.metadata } } diff --git a/compiler/testData/codegen/box/callableReference/function/kt53794_protectedJavaMember.kt b/compiler/testData/codegen/box/callableReference/function/kt53794_protectedJavaMember.kt new file mode 100644 index 00000000000..8892e62a4e6 --- /dev/null +++ b/compiler/testData/codegen/box/callableReference/function/kt53794_protectedJavaMember.kt @@ -0,0 +1,18 @@ +// TARGET_BACKEND: JVM +// FILE: B.kt + +class B : C() { + fun test(): String = bar(this::foo) +} + +fun bar(f: () -> String): String = f() + +fun box(): String = B().test() + +// FILE: C.java + +public class C { + protected final String foo() { + return "OK"; + } +} diff --git a/compiler/testData/codegen/bytecodeText/callableReference/noMetadata.kt b/compiler/testData/codegen/bytecodeText/callableReference/noMetadata.kt new file mode 100644 index 00000000000..ca59edba5b3 --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/callableReference/noMetadata.kt @@ -0,0 +1,9 @@ +// TARGET_BACKEND: JVM_IR + +fun f() {} +fun g() = ::f + +// This regexp checks that there's only one class annotated with kotlin.Metadata with the actual data (which is in the `d1` field). +// That class is the file facade. The synthetic class for the reference `::f` should be generated with synthetic metadata, i.e. +// which has nothing in the `d1` field. +// 1 @Lkotlin/Metadata;\(.*d1.*\) 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 7e031cf5e06..ea60211f29d 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 @@ -4002,6 +4002,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/callableReference/function/kt47741.kt"); } + @Test + @TestMetadata("kt53794_protectedJavaMember.kt") + public void testKt53794_protectedJavaMember() throws Exception { + runTest("compiler/testData/codegen/box/callableReference/function/kt53794_protectedJavaMember.kt"); + } + @Test @TestMetadata("nestedConstructorFromClass.kt") public void testNestedConstructorFromClass() 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 5f640b2f136..f4608a1f5af 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 @@ -4116,6 +4116,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/callableReference/function/kt47741.kt"); } + @Test + @TestMetadata("kt53794_protectedJavaMember.kt") + public void testKt53794_protectedJavaMember() throws Exception { + runTest("compiler/testData/codegen/box/callableReference/function/kt53794_protectedJavaMember.kt"); + } + @Test @TestMetadata("nestedConstructorFromClass.kt") public void testNestedConstructorFromClass() 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 1ecaf08c58e..dfb37ee1dbe 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 @@ -958,6 +958,12 @@ public class IrBytecodeTextTestGenerated extends AbstractIrBytecodeTextTest { runTest("compiler/testData/codegen/bytecodeText/callableReference/nameIntrinsicWithImplicitThis.kt"); } + @Test + @TestMetadata("noMetadata.kt") + public void testNoMetadata() throws Exception { + runTest("compiler/testData/codegen/bytecodeText/callableReference/noMetadata.kt"); + } + @Test @TestMetadata("unboundFieldReferenceInInline.kt") public void testUnboundFieldReferenceInInline() 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 fc742ca4654..71d9c854e48 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -3498,6 +3498,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTest("compiler/testData/codegen/box/callableReference/function/kt47741.kt"); } + @TestMetadata("kt53794_protectedJavaMember.kt") + public void testKt53794_protectedJavaMember() throws Exception { + runTest("compiler/testData/codegen/box/callableReference/function/kt53794_protectedJavaMember.kt"); + } + @TestMetadata("nestedConstructorFromClass.kt") public void testNestedConstructorFromClass() throws Exception { runTest("compiler/testData/codegen/box/callableReference/function/nestedConstructorFromClass.kt");