diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/CallAndReferenceGenerator.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/CallAndReferenceGenerator.kt index 668dca6fb54..572328dd856 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/CallAndReferenceGenerator.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/CallAndReferenceGenerator.kt @@ -166,7 +166,6 @@ class CallAndReferenceGenerator( } } - // TODO: handle transient receiver, such as class symbol, like A::foo val boundReceiver = boundDispatchReceiver ?: boundExtensionReceiver if (boundReceiver == null) { IrFunctionExpressionImpl(startOffset, endOffset, type, irAdapterFunction, IrStatementOrigin.ADAPTED_FUNCTION_REFERENCE) @@ -306,6 +305,7 @@ class CallAndReferenceGenerator( error("unknown callee kind: ${adapteeFunction.render()}") } + var shift = 0 if (boundDispatchReceiver != null || boundExtensionReceiver != null) { val receiverValue = IrGetValueImpl( startOffset, endOffset, adapterFunction.extensionReceiverParameter!!.symbol, IrStatementOrigin.ADAPTED_FUNCTION_REFERENCE @@ -314,20 +314,34 @@ class CallAndReferenceGenerator( boundDispatchReceiver != null -> irCall.dispatchReceiver = receiverValue boundExtensionReceiver != null -> irCall.extensionReceiver = receiverValue } + } else if (callableReferenceAccess.explicitReceiver is FirResolvedQualifier) { + // Unbound callable reference 'A::foo' + val adaptedReceiverParameter = adapterFunction.valueParameters[0] + val adaptedReceiverValue = IrGetValueImpl( + startOffset, endOffset, adaptedReceiverParameter.type, adaptedReceiverParameter.symbol + ) + if (adapteeFunction.extensionReceiverParameter != null) { + irCall.extensionReceiver = adaptedReceiverValue + shift = 1 + } else { + irCall.dispatchReceiver = adaptedReceiverValue + } } adapteeFunction.valueParameters.mapIndexed { index, valueParameter -> when { valueParameter.hasDefaultValue() -> { - irCall.putValueArgument(index, null) + irCall.putValueArgument(shift + index, null) } valueParameter.isVararg -> { // TODO: handle vararg and spread - irCall.putValueArgument(index, null) + irCall.putValueArgument(shift + index, null) } else -> { val irValueArgument = adapterFunction.valueParameters[index] - irCall.putValueArgument(index, IrGetValueImpl(startOffset, endOffset, irValueArgument.type, irValueArgument.symbol)) + irCall.putValueArgument( + shift + index, IrGetValueImpl(startOffset, endOffset, irValueArgument.type, irValueArgument.symbol) + ) } } } diff --git a/compiler/testData/codegen/box/callableReference/equality/coercionToUnit.kt b/compiler/testData/codegen/box/callableReference/equality/coercionToUnit.kt index 36bfc3b3d88..8d64c599bd2 100644 --- a/compiler/testData/codegen/box/callableReference/equality/coercionToUnit.kt +++ b/compiler/testData/codegen/box/callableReference/equality/coercionToUnit.kt @@ -1,6 +1,5 @@ // IGNORE_BACKEND: JS, JS_IR, NATIVE // IGNORE_BACKEND: JS_IR_ES6 -// IGNORE_BACKEND_FIR: JVM_IR // FILE: test.kt fun checkEqual(x: Any, y: Any) { diff --git a/compiler/testData/codegen/box/callableReference/serializability/adaptedReferences.kt b/compiler/testData/codegen/box/callableReference/serializability/adaptedReferences.kt index ead65b36610..89736604ce4 100644 --- a/compiler/testData/codegen/box/callableReference/serializability/adaptedReferences.kt +++ b/compiler/testData/codegen/box/callableReference/serializability/adaptedReferences.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR // TARGET_BACKEND: JVM // WITH_REFLECT diff --git a/compiler/testData/ir/irText/expressions/callableReferences/unboundMemberReferenceWithAdaptedArguments.fir.txt b/compiler/testData/ir/irText/expressions/callableReferences/unboundMemberReferenceWithAdaptedArguments.fir.txt index d771cf96f96..4fca87281ae 100644 --- a/compiler/testData/ir/irText/expressions/callableReferences/unboundMemberReferenceWithAdaptedArguments.fir.txt +++ b/compiler/testData/ir/irText/expressions/callableReferences/unboundMemberReferenceWithAdaptedArguments.fir.txt @@ -66,6 +66,7 @@ FILE fqName: fileName:/unboundMemberReferenceWithAdaptedArguments.kt VALUE_PARAMETER ADAPTER_PARAMETER_FOR_CALLABLE_REFERENCE name:p1 index:1 type:kotlin.Int BLOCK_BODY CALL 'public open fun foo (vararg xs: kotlin.Int): kotlin.Int declared in .A' type=kotlin.Int origin=null + $this: GET_VAR 'p0: .A declared in .testUnbound.foo' type=.A origin=null FUN name:testBound visibility:public modality:FINAL <> (a:.A) returnType:kotlin.Unit VALUE_PARAMETER name:a index:0 type:.A BLOCK_BODY