diff --git a/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java b/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java index b1ed6288ce8..9b6f34829f2 100644 --- a/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java +++ b/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java @@ -2045,6 +2045,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT runTest("compiler/testData/codegen/box/callableReference/bound/companionObjectReceiver.kt"); } + @TestMetadata("dontShareReceiver.kt") + public void testDontShareReceiver() throws Exception { + runTest("compiler/testData/codegen/box/callableReference/bound/dontShareReceiver.kt"); + } + @TestMetadata("emptyLHS.kt") public void testEmptyLHS() throws Exception { runTest("compiler/testData/codegen/box/callableReference/bound/emptyLHS.kt"); diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/CallableReferenceLowering.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/CallableReferenceLowering.kt index dbcac3513d0..5ffd163e8b7 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/CallableReferenceLowering.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/CallableReferenceLowering.kt @@ -14,10 +14,8 @@ import org.jetbrains.kotlin.backend.common.lower.createIrBuilder import org.jetbrains.kotlin.backend.common.runOnFilePostfix import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET +import org.jetbrains.kotlin.ir.builders.* import org.jetbrains.kotlin.ir.builders.declarations.* -import org.jetbrains.kotlin.ir.builders.irBlockBody -import org.jetbrains.kotlin.ir.builders.irDelegatingConstructorCall -import org.jetbrains.kotlin.ir.builders.setSourceRange import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.impl.IrValueParameterImpl import org.jetbrains.kotlin.ir.descriptors.WrappedReceiverParameterDescriptor @@ -27,10 +25,7 @@ import org.jetbrains.kotlin.ir.symbols.impl.IrValueParameterSymbolImpl import org.jetbrains.kotlin.ir.types.IrSimpleType import org.jetbrains.kotlin.ir.types.IrTypeProjection import org.jetbrains.kotlin.ir.types.classOrNull -import org.jetbrains.kotlin.ir.util.defaultType -import org.jetbrains.kotlin.ir.util.explicitParameters -import org.jetbrains.kotlin.ir.util.isSuspend -import org.jetbrains.kotlin.ir.util.parentAsClass +import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid import org.jetbrains.kotlin.name.Name @@ -84,8 +79,16 @@ class CallableReferenceLowering(private val context: CommonBackendContext) : Bod clazz.parent = container return expression.run { - val ctorCall = - IrConstructorCallImpl(startOffset, endOffset, type, ctor.symbol, 0 /*TODO: properly set type arguments*/, 0, 0, CALLABLE_REFERENCE_CREATE) + val boundReceiver = expression.run { dispatchReceiver ?: extensionReceiver } + val vpCount = if (boundReceiver != null) 1 else 0 + val ctorCall = IrConstructorCallImpl( + startOffset, endOffset, type, ctor.symbol, + 0 /*TODO: properly set type arguments*/, 0, + vpCount, CALLABLE_REFERENCE_CREATE).apply { + boundReceiver?.let { + putValueArgument(0, it) + } + } IrCompositeImpl(startOffset, endOffset, type, origin, listOf(clazz, ctorCall)) } } @@ -138,10 +141,7 @@ class CallableReferenceLowering(private val context: CommonBackendContext) : Bod val boundReceiver = funRef.run { dispatchReceiver ?: extensionReceiver } if (boundReceiver != null) { - boundReceiverField = addField(BOUND_RECEIVER_NAME, boundReceiver.type).apply { - initializer = IrExpressionBodyImpl(boundReceiver.startOffset, boundReceiver.endOffset, boundReceiver) - parent = this@createReceiverField - } + boundReceiverField = addField(BOUND_RECEIVER_NAME, boundReceiver.type) } } @@ -162,6 +162,14 @@ class CallableReferenceLowering(private val context: CommonBackendContext) : Bod val superConstructor = superClass.classOrNull!!.owner.declarations.single { it is IrConstructor && it.isPrimary } as IrConstructor + val boundReceiverParameter = boundReceiverField?.let { + addValueParameter { + name = BOUND_RECEIVER_NAME + type = it.type + index = 0 + } + } + var continuation: IrValueParameter? = null if (isSuspendLambda) { @@ -169,7 +177,7 @@ class CallableReferenceLowering(private val context: CommonBackendContext) : Bod continuation = addValueParameter { name = superContinuation.name type = superContinuation.type - index = 0 + index = if (boundReceiverParameter == null) 0 else 1 } } @@ -179,6 +187,9 @@ class CallableReferenceLowering(private val context: CommonBackendContext) : Bod putValueArgument(0, getValue(it)) } } + boundReceiverParameter?.let { + +irSetField(irGet(clazz.thisReceiver!!), boundReceiverField!!, irGet(it)) + } +IrInstanceInitializerCallImpl(startOffset, endOffset, clazz.symbol, context.irBuiltIns.unitType) } } diff --git a/compiler/testData/codegen/box/callableReference/bound/dontShareReceiver.kt b/compiler/testData/codegen/box/callableReference/bound/dontShareReceiver.kt new file mode 100644 index 00000000000..a6775e73eba --- /dev/null +++ b/compiler/testData/codegen/box/callableReference/bound/dontShareReceiver.kt @@ -0,0 +1,12 @@ +// IGNORE_BACKEND_FIR: JVM_IR + +fun box(): String { + var state = 0 + val f = (state++)::toString + val s1 = f() + if (s1 != "0") return "fail 1: $s1" + ++state + val s2 = f() + if (s2 != "0") return "fail 2: $s2" + return "OK" +} \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index dd8ccb15191..a5aaa640263 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -2065,6 +2065,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/callableReference/bound/companionObjectReceiver.kt"); } + @TestMetadata("dontShareReceiver.kt") + public void testDontShareReceiver() throws Exception { + runTest("compiler/testData/codegen/box/callableReference/bound/dontShareReceiver.kt"); + } + @TestMetadata("emptyLHS.kt") public void testEmptyLHS() throws Exception { runTest("compiler/testData/codegen/box/callableReference/bound/emptyLHS.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index 271ca580b32..60bc87e3d09 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -2065,6 +2065,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTest("compiler/testData/codegen/box/callableReference/bound/companionObjectReceiver.kt"); } + @TestMetadata("dontShareReceiver.kt") + public void testDontShareReceiver() throws Exception { + runTest("compiler/testData/codegen/box/callableReference/bound/dontShareReceiver.kt"); + } + @TestMetadata("emptyLHS.kt") public void testEmptyLHS() throws Exception { runTest("compiler/testData/codegen/box/callableReference/bound/emptyLHS.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java index cfabe030e18..2e114811179 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java @@ -2045,6 +2045,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/callableReference/bound/companionObjectReceiver.kt"); } + @TestMetadata("dontShareReceiver.kt") + public void testDontShareReceiver() throws Exception { + runTest("compiler/testData/codegen/box/callableReference/bound/dontShareReceiver.kt"); + } + @TestMetadata("emptyLHS.kt") public void testEmptyLHS() throws Exception { runTest("compiler/testData/codegen/box/callableReference/bound/emptyLHS.kt"); diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java index 593de932148..fb6bbd2c925 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java @@ -1480,6 +1480,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest { runTest("compiler/testData/codegen/box/callableReference/bound/companionObjectReceiver.kt"); } + @TestMetadata("dontShareReceiver.kt") + public void testDontShareReceiver() throws Exception { + runTest("compiler/testData/codegen/box/callableReference/bound/dontShareReceiver.kt"); + } + @TestMetadata("emptyLHS.kt") public void testEmptyLHS() throws Exception { runTest("compiler/testData/codegen/box/callableReference/bound/emptyLHS.kt"); diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java index 9abe23d264b..a730a9ad736 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java @@ -1480,6 +1480,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { runTest("compiler/testData/codegen/box/callableReference/bound/companionObjectReceiver.kt"); } + @TestMetadata("dontShareReceiver.kt") + public void testDontShareReceiver() throws Exception { + runTest("compiler/testData/codegen/box/callableReference/bound/dontShareReceiver.kt"); + } + @TestMetadata("emptyLHS.kt") public void testEmptyLHS() throws Exception { runTest("compiler/testData/codegen/box/callableReference/bound/emptyLHS.kt");