From e1795984570031b3c80751799a64f17d924c37a6 Mon Sep 17 00:00:00 2001 From: Dmitry Petrov Date: Tue, 30 Nov 2021 15:08:33 +0300 Subject: [PATCH] JVM_IR KT-47939 equality for fun interface constructor references --- .../FirBlackBoxCodegenTestGenerated.java | 12 ++++ .../jvm/lower/FunctionReferenceLowering.kt | 59 +++++++++++++++---- .../jvm/lower/GenerateMultifileFacades.kt | 1 + .../backend/jvm/codegen/ClassCodegen.kt | 5 +- .../funInterfaceConstructedObjectsEquality.kt | 43 ++++++++++++++ .../funInterfaceConstructor.kt | 3 +- .../funInterfaceConstructorEquality.kt | 41 +++++++++++++ .../codegen/BlackBoxCodegenTestGenerated.java | 6 ++ .../IrBlackBoxCodegenTestGenerated.java | 12 ++++ .../LightAnalysisModeTestGenerated.java | 5 ++ .../js/test/JsCodegenBoxTestGenerated.java | 12 ++++ .../test/ir/IrJsCodegenBoxTestGenerated.java | 12 ++++ .../IrCodegenBoxWasmTestGenerated.java | 10 ++++ .../jvm/internal/FunctionReference.java | 6 ++ .../NativeExtBlackBoxTestGenerated.java | 12 ++++ 15 files changed, 226 insertions(+), 13 deletions(-) create mode 100644 compiler/testData/codegen/box/callableReference/funInterfaceConstructor/funInterfaceConstructedObjectsEquality.kt create mode 100644 compiler/testData/codegen/box/callableReference/funInterfaceConstructor/funInterfaceConstructorEquality.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 2a9dbe9a9c2..684c7858a64 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 @@ -3585,11 +3585,23 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/callableReference/funInterfaceConstructor"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true); } + @Test + @TestMetadata("funInterfaceConstructedObjectsEquality.kt") + public void testFunInterfaceConstructedObjectsEquality() throws Exception { + runTest("compiler/testData/codegen/box/callableReference/funInterfaceConstructor/funInterfaceConstructedObjectsEquality.kt"); + } + @Test @TestMetadata("funInterfaceConstructor.kt") public void testFunInterfaceConstructor() throws Exception { runTest("compiler/testData/codegen/box/callableReference/funInterfaceConstructor/funInterfaceConstructor.kt"); } + + @Test + @TestMetadata("funInterfaceConstructorEquality.kt") + public void testFunInterfaceConstructorEquality() throws Exception { + runTest("compiler/testData/codegen/box/callableReference/funInterfaceConstructor/funInterfaceConstructorEquality.kt"); + } } @Nested 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 d438a1e7a9b..38fbb61d30d 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 @@ -28,6 +28,7 @@ import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl import org.jetbrains.kotlin.ir.declarations.impl.IrVariableImpl import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.expressions.impl.* +import org.jetbrains.kotlin.ir.symbols.IrClassSymbol import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol import org.jetbrains.kotlin.ir.symbols.impl.IrVariableSymbolImpl import org.jetbrains.kotlin.ir.types.* @@ -571,7 +572,16 @@ internal class FunctionReferenceLowering(private val context: JvmBackendContext) } private val adaptedReferenceOriginalTarget: IrFunction? = adapteeCall?.symbol?.owner - private val isAdaptedReference = adaptedReferenceOriginalTarget != null + private val isAdaptedFunInterfaceConstructorReference = + callee.origin == IrDeclarationOrigin.ADAPTER_FOR_FUN_INTERFACE_CONSTRUCTOR + private val constructedFunInterfaceSymbol: IrClassSymbol? = + if (isAdaptedFunInterfaceConstructorReference) + callee.returnType.classOrNull + ?: throw AssertionError("Fun interface type expected: ${callee.returnType.render()}") + else + null + private val isAdaptedReference = + isAdaptedFunInterfaceConstructorReference || adaptedReferenceOriginalTarget != null private val samInterface = samSuperType?.getClass() private val isKotlinFunInterface = samInterface != null && !samInterface.isFromJava() @@ -580,14 +590,15 @@ internal class FunctionReferenceLowering(private val context: JvmBackendContext) isKotlinFunInterface && (isAdaptedReference || !isLambda) private val superType = - samSuperType ?: when { - isLambda -> context.ir.symbols.lambdaClass - useOptimizedSuperClass -> when { - isAdaptedReference -> context.ir.symbols.adaptedFunctionReference - else -> context.ir.symbols.functionReferenceImpl - } - else -> context.ir.symbols.functionReference - }.defaultType + samSuperType + ?: when { + isLambda -> context.ir.symbols.lambdaClass + useOptimizedSuperClass -> when { + isAdaptedReference -> context.ir.symbols.adaptedFunctionReference + else -> context.ir.symbols.functionReferenceImpl + } + else -> context.ir.symbols.functionReference + }.defaultType private val functionReferenceClass = context.irFactory.buildClass { setSourceRange(irFunctionReference) @@ -770,7 +781,17 @@ internal class FunctionReferenceLowering(private val context: JvmBackendContext) if (boundReceiver != null) { call.putValueArgument(index++, generateBoundReceiver()) } - if (!isLambda && useOptimizedSuperClass) { + if (isAdaptedFunInterfaceConstructorReference) { + val owner = kClassReference(constructedFunInterfaceSymbol!!.owner.defaultType) + // owner: + call.putValueArgument(index++, kClassToJavaClass(owner)) + // name: "" + call.putValueArgument(index++, irString("")) + // signature: "" + call.putValueArgument(index++, irString("")) + // flags: 8 = 4 << 1 + call.putValueArgument(index, irInt(8)) + } else if (!isLambda && useOptimizedSuperClass) { val callableReferenceTarget = adaptedReferenceOriginalTarget ?: callee val owner = calculateOwnerKClass(callableReferenceTarget.parent) call.putValueArgument(index++, kClassToJavaClass(owner)) @@ -824,7 +845,12 @@ internal class FunctionReferenceLowering(private val context: JvmBackendContext) IrDeclarationOrigin.INSTANCE_RECEIVER, functionReferenceClass.symbol.defaultType ) - if (isLambda) createLambdaInvokeMethod() else createFunctionReferenceInvokeMethod(receiverVar) + if (isLambda) + createLambdaInvokeMethod() + else if (isAdaptedFunInterfaceConstructorReference) + createFunInterfaceConstructorInvokeMethod() + else + createFunctionReferenceInvokeMethod(receiverVar) } // Inline the body of an anonymous function into the generated lambda subclass. @@ -835,6 +861,17 @@ internal class FunctionReferenceLowering(private val context: JvmBackendContext) } valueParameters += valueParameterMap.values body = callee.moveBodyTo(this, valueParameterMap) + + } + + private fun IrSimpleFunction.createFunInterfaceConstructorInvokeMethod() { + val adapterValueParameter = callee.valueParameters.singleOrNull() + ?: throw AssertionError("Single value parameter expected: ${callee.render()}") + val invokeValueParameter = adapterValueParameter.copyTo(this, index = 0) + val valueParameterMap = mapOf(adapterValueParameter to invokeValueParameter) + valueParameters = listOf(invokeValueParameter) + body = callee.moveBodyTo(this, valueParameterMap) + callee.body = null } private fun IrSimpleFunction.createFunctionReferenceInvokeMethod(receiver: IrValueDeclaration?) { diff --git a/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/GenerateMultifileFacades.kt b/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/GenerateMultifileFacades.kt index f43c1e8fc45..51bfd5af7f5 100644 --- a/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/GenerateMultifileFacades.kt +++ b/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/GenerateMultifileFacades.kt @@ -223,6 +223,7 @@ private fun IrSimpleFunction.createMultifileDelegateIfNeeded( origin == JvmLoweredDeclarationOrigin.INLINE_LAMBDA || origin == IrDeclarationOrigin.LOCAL_FUNCTION_FOR_LAMBDA || origin == IrDeclarationOrigin.PROPERTY_DELEGATE || + origin == IrDeclarationOrigin.ADAPTER_FOR_FUN_INTERFACE_CONSTRUCTOR || // $annotations methods in the facade are only needed for const properties. (origin == JvmLoweredDeclarationOrigin.SYNTHETIC_METHOD_FOR_PROPERTY_OR_TYPEALIAS_ANNOTATIONS && (metadata as? MetadataSource.Property)?.isConst != true) diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ClassCodegen.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ClassCodegen.kt index 70d336485cd..843b2dd30e3 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ClassCodegen.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ClassCodegen.kt @@ -145,7 +145,10 @@ class ClassCodegen private constructor( val smap = context.getSourceMapper(irClass) // 1. Any method other than `` can add a field and a `` statement: for (method in irClass.declarations.filterIsInstance()) { - if (method.name.asString() != "" && method.origin != JvmLoweredDeclarationOrigin.INLINE_LAMBDA) { + if (method.name.asString() != "" && + method.origin != JvmLoweredDeclarationOrigin.INLINE_LAMBDA && + method.origin != IrDeclarationOrigin.ADAPTER_FOR_FUN_INTERFACE_CONSTRUCTOR + ) { generateMethod(method, smap) } } diff --git a/compiler/testData/codegen/box/callableReference/funInterfaceConstructor/funInterfaceConstructedObjectsEquality.kt b/compiler/testData/codegen/box/callableReference/funInterfaceConstructor/funInterfaceConstructedObjectsEquality.kt new file mode 100644 index 00000000000..6cbce70d949 --- /dev/null +++ b/compiler/testData/codegen/box/callableReference/funInterfaceConstructor/funInterfaceConstructedObjectsEquality.kt @@ -0,0 +1,43 @@ +// !LANGUAGE: +AllowKotlinFunInterfaceConstructorReference + +// IGNORE_BACKEND: JVM +// ^ unsupported in old JVM BE + +// IGNORE_BACKEND: WASM +// ^ wasm-function[1893]:0x1cf8a: RuntimeError: dereferencing a null pointer + +// IGNORE_BACKEND: JS_IR +// ^ TypeError: tmp is not a function + +// FILE: funInterfaceConstructorEquality.kt + +val ks1: (() -> String) -> KSupplier = + ::KSupplier + +val ks11Foo = ks1(::foo) +val ks21Foo = ks2(::foo) + +fun box(): String { + if (ks11Foo != ks12Foo) + return "failed: ks11Foo != ks12Foo (same ctor, different source files)" + if (ks11Foo != ks21Foo) + return "failed: ks11Foo != ks21Foo (different ctors, same source file)" + if (ks11Foo != ks22Foo) + return "failed: ks11Foo != ks22Foo (different ctors, different source files)" + + return "OK" +} + +// FILE: KSupplier.kt + +fun interface KSupplier { + fun get(): T +} + +fun foo() = "abc" + +val ks2: (() -> String) -> KSupplier = + ::KSupplier + +val ks12Foo = ks1(::foo) +val ks22Foo = ks2(::foo) diff --git a/compiler/testData/codegen/box/callableReference/funInterfaceConstructor/funInterfaceConstructor.kt b/compiler/testData/codegen/box/callableReference/funInterfaceConstructor/funInterfaceConstructor.kt index f889ecad410..179f746548b 100644 --- a/compiler/testData/codegen/box/callableReference/funInterfaceConstructor/funInterfaceConstructor.kt +++ b/compiler/testData/codegen/box/callableReference/funInterfaceConstructor/funInterfaceConstructor.kt @@ -1,6 +1,7 @@ // !LANGUAGE: +AllowKotlinFunInterfaceConstructorReference + // IGNORE_BACKEND: JVM -// ^ feature supported in IR-based backends only +// ^ unsupported in old JVM BE fun interface KSupplier { fun get(): T diff --git a/compiler/testData/codegen/box/callableReference/funInterfaceConstructor/funInterfaceConstructorEquality.kt b/compiler/testData/codegen/box/callableReference/funInterfaceConstructor/funInterfaceConstructorEquality.kt new file mode 100644 index 00000000000..d23c19b5210 --- /dev/null +++ b/compiler/testData/codegen/box/callableReference/funInterfaceConstructor/funInterfaceConstructorEquality.kt @@ -0,0 +1,41 @@ +// !LANGUAGE: +AllowKotlinFunInterfaceConstructorReference + +// DONT_TARGET_EXACT_BACKEND: JVM +// ^ old JVM BE generates bogus code that fails in 'invoke', but works almost as expected in terms of equality + +// IGNORE_BACKEND: WASM +// ^ Failed: ks1 != ks2 (same file, same SAM type) + +// IGNORE_BACKEND: JS_IR +// ^ Failed: ks1 != ks2 (same file, same SAM type) + +// FILE: funInterfaceConstructorEquality.kt + +val ks1: (() -> String) -> KSupplier = + ::KSupplier + +val ks2: (() -> String) -> KSupplier = + ::KSupplier + +val kn1: (() -> Number) -> KSupplier = + ::KSupplier + +fun box(): String { + if (ks1 != ks2) + return "Failed: ks1 != ks2 (same file, same SAM type)" + if (ks1 != ks3) + return "Failed: ks1 != ks3 (different file, same SAM type)" + if (ks1 != kn1) + return "Failed: ks1 != kn1 (same file, same SAM interface, different type arguments)" + + return "OK" +} + +// FILE: KSupplier.kt + +fun interface KSupplier { + fun get(): T +} + +val ks3: (() -> String) -> KSupplier = + ::KSupplier 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 faba4db083c..05efc1895cf 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 @@ -3507,6 +3507,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/callableReference/funInterfaceConstructor"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true); } + @Test + @TestMetadata("funInterfaceConstructedObjectsEquality.kt") + public void testFunInterfaceConstructedObjectsEquality() throws Exception { + runTest("compiler/testData/codegen/box/callableReference/funInterfaceConstructor/funInterfaceConstructedObjectsEquality.kt"); + } + @Test @TestMetadata("funInterfaceConstructor.kt") public void testFunInterfaceConstructor() 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 1fa653bbee6..459cf8912a6 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 @@ -3585,11 +3585,23 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/callableReference/funInterfaceConstructor"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true); } + @Test + @TestMetadata("funInterfaceConstructedObjectsEquality.kt") + public void testFunInterfaceConstructedObjectsEquality() throws Exception { + runTest("compiler/testData/codegen/box/callableReference/funInterfaceConstructor/funInterfaceConstructedObjectsEquality.kt"); + } + @Test @TestMetadata("funInterfaceConstructor.kt") public void testFunInterfaceConstructor() throws Exception { runTest("compiler/testData/codegen/box/callableReference/funInterfaceConstructor/funInterfaceConstructor.kt"); } + + @Test + @TestMetadata("funInterfaceConstructorEquality.kt") + public void testFunInterfaceConstructorEquality() throws Exception { + runTest("compiler/testData/codegen/box/callableReference/funInterfaceConstructor/funInterfaceConstructorEquality.kt"); + } } @Nested diff --git a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index 7121bdc92bc..d57eeec5474 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -3068,6 +3068,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) public static class FunInterfaceConstructor extends AbstractLightAnalysisModeTest { + @TestMetadata("funInterfaceConstructedObjectsEquality.kt") + public void ignoreFunInterfaceConstructedObjectsEquality() throws Exception { + runTest("compiler/testData/codegen/box/callableReference/funInterfaceConstructor/funInterfaceConstructedObjectsEquality.kt"); + } + @TestMetadata("funInterfaceConstructor.kt") public void ignoreFunInterfaceConstructor() throws Exception { runTest("compiler/testData/codegen/box/callableReference/funInterfaceConstructor/funInterfaceConstructor.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 34b02c8c4d2..a65b165fffa 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 @@ -2445,11 +2445,23 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/callableReference/funInterfaceConstructor"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS, true); } + @Test + @TestMetadata("funInterfaceConstructedObjectsEquality.kt") + public void testFunInterfaceConstructedObjectsEquality() throws Exception { + runTest("compiler/testData/codegen/box/callableReference/funInterfaceConstructor/funInterfaceConstructedObjectsEquality.kt"); + } + @Test @TestMetadata("funInterfaceConstructor.kt") public void testFunInterfaceConstructor() throws Exception { runTest("compiler/testData/codegen/box/callableReference/funInterfaceConstructor/funInterfaceConstructor.kt"); } + + @Test + @TestMetadata("funInterfaceConstructorEquality.kt") + public void testFunInterfaceConstructorEquality() throws Exception { + runTest("compiler/testData/codegen/box/callableReference/funInterfaceConstructor/funInterfaceConstructorEquality.kt"); + } } @Nested 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 d8a110ef863..569ba50fa52 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 @@ -2487,11 +2487,23 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest { KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/callableReference/funInterfaceConstructor"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR, true); } + @Test + @TestMetadata("funInterfaceConstructedObjectsEquality.kt") + public void testFunInterfaceConstructedObjectsEquality() throws Exception { + runTest("compiler/testData/codegen/box/callableReference/funInterfaceConstructor/funInterfaceConstructedObjectsEquality.kt"); + } + @Test @TestMetadata("funInterfaceConstructor.kt") public void testFunInterfaceConstructor() throws Exception { runTest("compiler/testData/codegen/box/callableReference/funInterfaceConstructor/funInterfaceConstructor.kt"); } + + @Test + @TestMetadata("funInterfaceConstructorEquality.kt") + public void testFunInterfaceConstructorEquality() throws Exception { + runTest("compiler/testData/codegen/box/callableReference/funInterfaceConstructor/funInterfaceConstructorEquality.kt"); + } } @Nested 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 a19ba2b15d3..c66a4bb8db0 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 @@ -2216,10 +2216,20 @@ public class IrCodegenBoxWasmTestGenerated extends AbstractIrCodegenBoxWasmTest KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/callableReference/funInterfaceConstructor"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.WASM, true); } + @TestMetadata("funInterfaceConstructedObjectsEquality.kt") + public void testFunInterfaceConstructedObjectsEquality() throws Exception { + runTest("compiler/testData/codegen/box/callableReference/funInterfaceConstructor/funInterfaceConstructedObjectsEquality.kt"); + } + @TestMetadata("funInterfaceConstructor.kt") public void testFunInterfaceConstructor() throws Exception { runTest("compiler/testData/codegen/box/callableReference/funInterfaceConstructor/funInterfaceConstructor.kt"); } + + @TestMetadata("funInterfaceConstructorEquality.kt") + public void testFunInterfaceConstructorEquality() throws Exception { + runTest("compiler/testData/codegen/box/callableReference/funInterfaceConstructor/funInterfaceConstructorEquality.kt"); + } } @TestMetadata("compiler/testData/codegen/box/callableReference/function") diff --git a/libraries/stdlib/jvm/runtime/kotlin/jvm/internal/FunctionReference.java b/libraries/stdlib/jvm/runtime/kotlin/jvm/internal/FunctionReference.java index 1d3285d28d3..4d0d1b12c82 100644 --- a/libraries/stdlib/jvm/runtime/kotlin/jvm/internal/FunctionReference.java +++ b/libraries/stdlib/jvm/runtime/kotlin/jvm/internal/FunctionReference.java @@ -31,6 +31,12 @@ public class FunctionReference extends CallableReference implements FunctionBase * fun useSuspend(f: suspend () -> Unit) {} * useSuspend(::target) * + *
    4 - whether it is a synthetic fun interface constructor, i.e.,
    +     *         fun interface KRunnable {
    +     *             fun run()
    +     *         }
    +     *         val kr: (() -> Unit) -> KRunnable = ::KRunnable
    +     *     
* */ @SinceKotlin(version = "1.4") diff --git a/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/NativeExtBlackBoxTestGenerated.java b/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/NativeExtBlackBoxTestGenerated.java index 8ad0197d475..d7d837691b7 100644 --- a/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/NativeExtBlackBoxTestGenerated.java +++ b/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/NativeExtBlackBoxTestGenerated.java @@ -2517,11 +2517,23 @@ public class NativeExtBlackBoxTestGenerated extends AbstractNativeBlackBoxTest { KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/callableReference/funInterfaceConstructor"), Pattern.compile("^(.+)\\.kt$"), null, true); } + @Test + @TestMetadata("funInterfaceConstructedObjectsEquality.kt") + public void testFunInterfaceConstructedObjectsEquality() throws Exception { + runTest("compiler/testData/codegen/box/callableReference/funInterfaceConstructor/funInterfaceConstructedObjectsEquality.kt"); + } + @Test @TestMetadata("funInterfaceConstructor.kt") public void testFunInterfaceConstructor() throws Exception { runTest("compiler/testData/codegen/box/callableReference/funInterfaceConstructor/funInterfaceConstructor.kt"); } + + @Test + @TestMetadata("funInterfaceConstructorEquality.kt") + public void testFunInterfaceConstructorEquality() throws Exception { + runTest("compiler/testData/codegen/box/callableReference/funInterfaceConstructor/funInterfaceConstructorEquality.kt"); + } } @Nested