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 715412eba47..e57692aff42 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 @@ -2542,6 +2542,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT runTest("compiler/testData/codegen/box/callableReference/kt44483.kt"); } + @Test + @TestMetadata("kt46902.kt") + public void testKt46902() throws Exception { + runTest("compiler/testData/codegen/box/callableReference/kt46902.kt"); + } + @Test @TestMetadata("nested.kt") public void testNested() throws Exception { diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/InlineCallableReferenceToLambda.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/InlineCallableReferenceToLambda.kt index 59a8455f8ba..8b9623546a8 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/InlineCallableReferenceToLambda.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/InlineCallableReferenceToLambda.kt @@ -23,7 +23,6 @@ import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.expressions.impl.IrFunctionReferenceImpl import org.jetbrains.kotlin.ir.types.IrSimpleType -import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.types.IrTypeProjection import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid @@ -125,43 +124,10 @@ private class InlineCallableReferenceToLambdaTransformer( } } - private class BoundReceiver( - val receiverParameter: IrValueParameter, - val receiverValue: IrExpression, - val receiverType: IrType - ) - - private fun IrCallableReference<*>.getBoundReceiver(): BoundReceiver? { - val irFunction = when (this) { - is IrFunctionReference -> - this.symbol.owner - is IrPropertyReference -> - this.getter!!.owner - else -> - throw AssertionError("Unexpected callable reference: ${this.render()}") - } - - this.dispatchReceiver?.let { dispatchReceiver -> - val dispatchReceiverParameter = irFunction.dispatchReceiverParameter - ?: throw AssertionError("Referenced declaration '${this.symbol.owner.render()}' has no dispatch receiver: ${this.dump()}") - // NB in case of fake override of Base::foo in Child::foo, dispatch receiver type is Base, - // but we in fact need Child (because of accessor generation). - return BoundReceiver(dispatchReceiverParameter, dispatchReceiver, irFunction.parentAsClass.defaultType) - } - - this.extensionReceiver?.let { extensionReceiver -> - val extensionReceiverParameter = irFunction.extensionReceiverParameter - ?: throw AssertionError("Referenced declaration '${this.symbol.owner.render()}' has no extension receiver: ${this.dump()}") - return BoundReceiver(extensionReceiverParameter, extensionReceiver, extensionReceiverParameter.type) - } - - return null - } - private fun expandInlineFunctionReferenceToLambda(expression: IrCallableReference<*>, referencedFunction: IrFunction): IrExpression { val irBuilder = context.createJvmIrBuilder(currentScope!!.scope.scopeOwnerSymbol, expression.startOffset, expression.endOffset) return irBuilder.irBlock(expression, IrStatementOrigin.LAMBDA) { - val boundReceiver = expression.getBoundReceiver() + val (receiverParameter, receiverValue) = expression.getArgumentsWithIr().singleOrNull() ?: (null to null) val argumentTypes = (expression.type as IrSimpleType).arguments.dropLast(1).map { (it as IrTypeProjection).type } val function = context.irFactory.buildFun { @@ -173,8 +139,8 @@ private class InlineCallableReferenceToLambdaTransformer( isSuspend = referencedFunction.isSuspend }.apply { parent = currentDeclarationParent!! - if (boundReceiver != null) { - addExtensionReceiver(boundReceiver.receiverType) + if (receiverValue != null) { + addExtensionReceiver(receiverValue.type) } for ((index, argumentType) in argumentTypes.withIndex()) { addValueParameter { @@ -196,7 +162,7 @@ private class InlineCallableReferenceToLambdaTransformer( var unboundIndex = 0 for (parameter in referencedFunction.explicitParameters) { when { - boundReceiver?.receiverParameter == parameter -> + receiverParameter == parameter -> irGet(extensionReceiverParameter!!) parameter.isVararg && unboundIndex < argumentTypes.size && parameter.type == valueParameters[unboundIndex].type -> irGet(valueParameters[unboundIndex++]) @@ -225,7 +191,7 @@ private class InlineCallableReferenceToLambdaTransformer( origin = IrStatementOrigin.LAMBDA ).apply { copyAttributes(expression) - extensionReceiver = boundReceiver?.receiverValue + extensionReceiver = receiverValue } } } diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/PropertyReferenceLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/PropertyReferenceLowering.kt index eded6c1ed60..49d748df814 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/PropertyReferenceLowering.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/PropertyReferenceLowering.kt @@ -354,15 +354,7 @@ private class PropertyReferenceLowering(val context: JvmBackendContext) : IrElem val receiverFromField = boundReceiver?.let { irImplicitCast(irGetField(irGet(arguments[0]), backingField), it.type) } call.copyTypeArgumentsFrom(expression) call.dispatchReceiver = call.symbol.owner.dispatchReceiverParameter?.let { - receiverFromField ?: irImplicitCast( - irGet(arguments[1]), - // In `C::x`, the receiver must be cast to `C` in order to put accessors for protected - // properties in the correct class (box/syntheticAccessors/accessorForProtectedPropertyReference.kt). - // However, if `x` is a property of C's superclass, the type of `dispatchReceiverParameter` is not `C`. - // Since the receiver is not bound, the type of the property must be `KProperty1` or - // `KProperty2`. - ((expression.type as IrSimpleType).arguments.first() as IrTypeProjection).type - ) + receiverFromField ?: irImplicitCast(irGet(arguments[1]), expression.receiverType) } call.extensionReceiver = call.symbol.owner.extensionReceiverParameter?.let { if (call.symbol.owner.dispatchReceiverParameter == null) @@ -393,9 +385,9 @@ private class PropertyReferenceLowering(val context: JvmBackendContext) : IrElem field.isStatic -> null expression.dispatchReceiver != null -> - irImplicitCast(irGetField(irGet(arguments[0]), backingField), field.parentAsClass.defaultType) + irImplicitCast(irGetField(irGet(arguments[0]), backingField), expression.receiverType) else -> - irImplicitCast(irGet(arguments[1]), field.parentAsClass.defaultType) + irImplicitCast(irGet(arguments[1]), expression.receiverType) } referenceClass.addOverride(get!!) { arguments -> @@ -449,6 +441,12 @@ private class PropertyReferenceLowering(val context: JvmBackendContext) : IrElem } } + // In `value::x`, using `value`'s type is fine; but in `C::x`, the type of the receiver has to be `C`. + // This is *not* the type of `x`'s dispatch receiver if `x` is declared in a superclass of `C`, so we + // extract `C` from the reference's type, which is either `KProperty1` or `KProperty2`. + private val IrCallableReference<*>.receiverType + get() = dispatchReceiver?.type ?: ((type as IrSimpleType).arguments.first() as IrTypeProjection).type + private fun IrCallableReference<*>.getBoundReceiver(): IrExpression? { val callee = symbol.owner return if (callee is IrDeclaration && callee.isJvmStaticInObject()) { diff --git a/compiler/testData/codegen/box/callableReference/kt46902.kt b/compiler/testData/codegen/box/callableReference/kt46902.kt new file mode 100644 index 00000000000..1be29b3d86c --- /dev/null +++ b/compiler/testData/codegen/box/callableReference/kt46902.kt @@ -0,0 +1,12 @@ +class A { + inner class C(val m: String) { + fun test(): String { + m.f(::C) + return m + } + } +} + +inline fun String.f(g: (String) -> A.C): A.C = g(this) + +fun box(): String = A().C("OK").test() diff --git a/compiler/testData/codegen/box/syntheticAccessors/protectedJavaFieldAccessor/kt46578_delegated.kt b/compiler/testData/codegen/box/syntheticAccessors/protectedJavaFieldAccessor/kt46578_delegated.kt index 7dac6e89318..ec015b85cd9 100644 --- a/compiler/testData/codegen/box/syntheticAccessors/protectedJavaFieldAccessor/kt46578_delegated.kt +++ b/compiler/testData/codegen/box/syntheticAccessors/protectedJavaFieldAccessor/kt46578_delegated.kt @@ -1,7 +1,5 @@ // TARGET_BACKEND: JVM // WITH_RUNTIME -// IGNORE_BACKEND_FIR: JVM_IR -// ^ ::jpf is incorrectly represented as a reference to Base::jpf (should be: reference to fake override in Derived) // FILE: kt46578_delegated.kt import p.* diff --git a/compiler/testData/codegen/box/syntheticAccessors/protectedJavaFieldAccessor/kt46578_propertyRef.kt b/compiler/testData/codegen/box/syntheticAccessors/protectedJavaFieldAccessor/kt46578_propertyRef.kt index 0aea9ef584d..faeb6180d77 100644 --- a/compiler/testData/codegen/box/syntheticAccessors/protectedJavaFieldAccessor/kt46578_propertyRef.kt +++ b/compiler/testData/codegen/box/syntheticAccessors/protectedJavaFieldAccessor/kt46578_propertyRef.kt @@ -1,7 +1,5 @@ // TARGET_BACKEND: JVM // WITH_RUNTIME -// IGNORE_BACKEND_FIR: JVM_IR -// ^ ::jpf is incorrectly represented as a reference to Base::jpf (should be: reference to fake override in Derived) // FILE: kt46578_propertyRef.kt import p.* diff --git a/compiler/testData/codegen/box/syntheticAccessors/protectedMemberReferenceAccessor/kt46597_crossinline_jvmField_property.kt b/compiler/testData/codegen/box/syntheticAccessors/protectedMemberReferenceAccessor/kt46597_crossinline_jvmField_property.kt index e695aca4758..69b78cabeb0 100644 --- a/compiler/testData/codegen/box/syntheticAccessors/protectedMemberReferenceAccessor/kt46597_crossinline_jvmField_property.kt +++ b/compiler/testData/codegen/box/syntheticAccessors/protectedMemberReferenceAccessor/kt46597_crossinline_jvmField_property.kt @@ -1,5 +1,4 @@ // TARGET_BACKEND: JVM -// IGNORE_BACKEND_FIR: JVM_IR // WITH_RUNTIME // FILE: a.kt diff --git a/compiler/testData/codegen/box/syntheticAccessors/protectedMemberReferenceAccessor/kt46597_crossinline_method.kt b/compiler/testData/codegen/box/syntheticAccessors/protectedMemberReferenceAccessor/kt46597_crossinline_method.kt index c9e81a1118e..39bfad09e6a 100644 --- a/compiler/testData/codegen/box/syntheticAccessors/protectedMemberReferenceAccessor/kt46597_crossinline_method.kt +++ b/compiler/testData/codegen/box/syntheticAccessors/protectedMemberReferenceAccessor/kt46597_crossinline_method.kt @@ -1,5 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR - // FILE: a.kt package a diff --git a/compiler/testData/codegen/box/syntheticAccessors/protectedMemberReferenceAccessor/kt46597_crossinline_property.kt b/compiler/testData/codegen/box/syntheticAccessors/protectedMemberReferenceAccessor/kt46597_crossinline_property.kt index 9cd15e8b9fa..f36eb201c10 100644 --- a/compiler/testData/codegen/box/syntheticAccessors/protectedMemberReferenceAccessor/kt46597_crossinline_property.kt +++ b/compiler/testData/codegen/box/syntheticAccessors/protectedMemberReferenceAccessor/kt46597_crossinline_property.kt @@ -1,5 +1,4 @@ // IGNORE_BACKEND: WASM -// IGNORE_BACKEND_FIR: JVM_IR // FILE: a.kt package a diff --git a/compiler/testData/codegen/box/syntheticAccessors/protectedMemberReferenceAccessor/kt46597_java_field.kt b/compiler/testData/codegen/box/syntheticAccessors/protectedMemberReferenceAccessor/kt46597_java_field.kt index 2b8d03be5a8..5e2c500b91f 100644 --- a/compiler/testData/codegen/box/syntheticAccessors/protectedMemberReferenceAccessor/kt46597_java_field.kt +++ b/compiler/testData/codegen/box/syntheticAccessors/protectedMemberReferenceAccessor/kt46597_java_field.kt @@ -1,5 +1,4 @@ // TARGET_BACKEND: JVM -// IGNORE_BACKEND_FIR: JVM_IR // FILE: a/Base.java package a; 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 3ec55ff8213..87d71ed0a68 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 @@ -2542,6 +2542,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/callableReference/kt44483.kt"); } + @Test + @TestMetadata("kt46902.kt") + public void testKt46902() throws Exception { + runTest("compiler/testData/codegen/box/callableReference/kt46902.kt"); + } + @Test @TestMetadata("nested.kt") public void testNested() 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 f6c1f1b61b7..ca528f650ae 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 @@ -2542,6 +2542,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/callableReference/kt44483.kt"); } + @Test + @TestMetadata("kt46902.kt") + public void testKt46902() throws Exception { + runTest("compiler/testData/codegen/box/callableReference/kt46902.kt"); + } + @Test @TestMetadata("nested.kt") public void testNested() 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 29982920137..5796606ac7b 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -2230,6 +2230,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTest("compiler/testData/codegen/box/callableReference/kt44483.kt"); } + @TestMetadata("kt46902.kt") + public void testKt46902() throws Exception { + runTest("compiler/testData/codegen/box/callableReference/kt46902.kt"); + } + @TestMetadata("nested.kt") public void testNested() throws Exception { runTest("compiler/testData/codegen/box/callableReference/nested.kt"); diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java index 1309f1c445c..fc6227c1ead 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java @@ -1510,6 +1510,11 @@ public class IrJsCodegenBoxES6TestGenerated extends AbstractIrJsCodegenBoxES6Tes runTest("compiler/testData/codegen/box/callableReference/kt44483.kt"); } + @TestMetadata("kt46902.kt") + public void testKt46902() throws Exception { + runTest("compiler/testData/codegen/box/callableReference/kt46902.kt"); + } + @TestMetadata("nested.kt") public void testNested() throws Exception { runTest("compiler/testData/codegen/box/callableReference/nested.kt"); diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java index bc59c665378..62bdad27b15 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java @@ -1510,6 +1510,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest { runTest("compiler/testData/codegen/box/callableReference/kt44483.kt"); } + @TestMetadata("kt46902.kt") + public void testKt46902() throws Exception { + runTest("compiler/testData/codegen/box/callableReference/kt46902.kt"); + } + @TestMetadata("nested.kt") public void testNested() throws Exception { runTest("compiler/testData/codegen/box/callableReference/nested.kt"); diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java index a2bba36d781..571debd2f1d 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java @@ -1510,6 +1510,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { runTest("compiler/testData/codegen/box/callableReference/kt44483.kt"); } + @TestMetadata("kt46902.kt") + public void testKt46902() throws Exception { + runTest("compiler/testData/codegen/box/callableReference/kt46902.kt"); + } + @TestMetadata("nested.kt") public void testNested() throws Exception { runTest("compiler/testData/codegen/box/callableReference/nested.kt"); diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/wasm/semantics/IrCodegenBoxWasmTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/wasm/semantics/IrCodegenBoxWasmTestGenerated.java index 784d99d6cf9..7f2ecc67c0a 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/wasm/semantics/IrCodegenBoxWasmTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/wasm/semantics/IrCodegenBoxWasmTestGenerated.java @@ -1290,6 +1290,11 @@ public class IrCodegenBoxWasmTestGenerated extends AbstractIrCodegenBoxWasmTest runTest("compiler/testData/codegen/box/callableReference/kt37604.kt"); } + @TestMetadata("kt46902.kt") + public void testKt46902() throws Exception { + runTest("compiler/testData/codegen/box/callableReference/kt46902.kt"); + } + @TestMetadata("nested.kt") public void testNested() throws Exception { runTest("compiler/testData/codegen/box/callableReference/nested.kt");