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 55b627ae7fe..3ad6bf2dac2 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 @@ -3171,6 +3171,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT runTest("compiler/testData/codegen/box/callableReference/function/argumentTypes.kt"); } + @Test + @TestMetadata("argumentTypesNoinline.kt") + public void testArgumentTypesNoinline() throws Exception { + runTest("compiler/testData/codegen/box/callableReference/function/argumentTypesNoinline.kt"); + } + @Test @TestMetadata("booleanNotIntrinsic.kt") public void testBooleanNotIntrinsic() throws Exception { @@ -3237,6 +3243,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT runTest("compiler/testData/codegen/box/callableReference/function/constructorFromTopLevelOneStringArg.kt"); } + @Test + @TestMetadata("dispatchReceiverType.kt") + public void testDispatchReceiverType() throws Exception { + runTest("compiler/testData/codegen/box/callableReference/function/dispatchReceiverType.kt"); + } + @Test @TestMetadata("enumValueOfMethod.kt") public void testEnumValueOfMethod() 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 3299eee777a..f563f83d3b4 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,6 +23,7 @@ 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.IrTypeProjection import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid import org.jetbrains.kotlin.name.Name @@ -126,18 +127,8 @@ private class InlineCallableReferenceToLambdaTransformer( 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) { - // We find the number of parameters for constructed lambda from the type of the function reference, - // but the actual types have to be copied from referencedFunction; function reference argument type may be too - // specific because of approximation. See compiler/testData/codegen/box/callableReference/function/argumentTypes.kt val boundReceiver: Pair? = expression.getArgumentsWithIr().singleOrNull() - val nParams = (expression.type as IrSimpleType).arguments.size - 1 - val toDropAtStart = if (boundReceiver != null) 1 else 0 - val argumentTypes = referencedFunction.explicitParameters.drop(toDropAtStart).take(nParams).map { parameter -> - parameter.type.substitute( - referencedFunction.typeParameters, - referencedFunction.typeParameters.indices.map { expression.getTypeArgument(it)!! } - ) - } + val argumentTypes = (expression.type as IrSimpleType).arguments.dropLast(1).map { (it as IrTypeProjection).type } val function = context.irFactory.buildFun { setSourceRange(expression) diff --git a/compiler/testData/codegen/box/callableReference/function/argumentTypes.kt b/compiler/testData/codegen/box/callableReference/function/argumentTypes.kt index da45ae5b723..459465d976b 100644 --- a/compiler/testData/codegen/box/callableReference/function/argumentTypes.kt +++ b/compiler/testData/codegen/box/callableReference/function/argumentTypes.kt @@ -1,13 +1,11 @@ +// IGNORE_BACKEND: JVM_IR +// IGNORE_BACKEND_FIR: JVM_IR // DONT_TARGET_EXACT_BACKEND: WASM // WASM_MUTE_REASON: CALLABLE_REFERENCES_FAIL -inline fun id(x: TT): TT = x -inline fun String.extId(x: TT): String = this +fun id(x: T): T = x +fun String.extId(x: T): T = x -private fun ff(value: T?): String { - // In PSI2IR, the funcref is approximated to Function1> - value?.let(::id) - return value?.let("OK"::extId)!! -} - -fun box() = ff("arg") +fun foo(value: T?): T? = value?.let(::id) // KFunction1 +fun bar(value: T?): T? = value?.let(""::extId) +fun box() = foo("O")!! + foo("K")!! diff --git a/compiler/testData/codegen/box/callableReference/function/argumentTypesNoinline.kt b/compiler/testData/codegen/box/callableReference/function/argumentTypesNoinline.kt new file mode 100644 index 00000000000..afb44b7bf53 --- /dev/null +++ b/compiler/testData/codegen/box/callableReference/function/argumentTypesNoinline.kt @@ -0,0 +1,13 @@ +// IGNORE_BACKEND: JVM_IR +// IGNORE_BACKEND_FIR: JVM_IR +// DONT_TARGET_EXACT_BACKEND: WASM +// WASM_MUTE_REASON: CALLABLE_REFERENCES_FAIL +fun id(x: T): T = x +fun String.extId(x: T): T = x + +fun T.myLet(block: (T) -> R): R = block(this) + +fun foo(value: T?): T? = value?.myLet(::id) // KFunction1 +fun bar(value: T?): T? = value?.myLet(""::extId) + +fun box() = foo("O")!! + foo("K")!! diff --git a/compiler/testData/codegen/box/callableReference/function/dispatchReceiverType.kt b/compiler/testData/codegen/box/callableReference/function/dispatchReceiverType.kt new file mode 100644 index 00000000000..7c0d9007191 --- /dev/null +++ b/compiler/testData/codegen/box/callableReference/function/dispatchReceiverType.kt @@ -0,0 +1,28 @@ +// TARGET_BACKEND: JVM +// IGNORE_BACKEND_FIR: JVM_IR +// MODULE: lib +// FILE: X.java +package test; + +public class X extends PX { + public X(String x) { super(x); } +} + +// FILE: PX.java +package test; + +class PX { + private final String x; + + PX(String x) { this.x = x; } + + public String foo() { return x; } +} + +// MODULE: main(lib) +// FILE: box.kt +import test.X + +fun T.myLet(block: (T) -> R): R = block(this) + +fun box() = X("O").let(X::foo) + X("K").myLet(X::foo) 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 7458bb89d14..1949f55b6b8 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 @@ -3171,6 +3171,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/callableReference/function/argumentTypes.kt"); } + @Test + @TestMetadata("argumentTypesNoinline.kt") + public void testArgumentTypesNoinline() throws Exception { + runTest("compiler/testData/codegen/box/callableReference/function/argumentTypesNoinline.kt"); + } + @Test @TestMetadata("booleanNotIntrinsic.kt") public void testBooleanNotIntrinsic() throws Exception { @@ -3237,6 +3243,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/callableReference/function/constructorFromTopLevelOneStringArg.kt"); } + @Test + @TestMetadata("dispatchReceiverType.kt") + public void testDispatchReceiverType() throws Exception { + runTest("compiler/testData/codegen/box/callableReference/function/dispatchReceiverType.kt"); + } + @Test @TestMetadata("enumValueOfMethod.kt") public void testEnumValueOfMethod() 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 225e73d0485..d4db1feb7cc 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 @@ -3171,6 +3171,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/callableReference/function/argumentTypes.kt"); } + @Test + @TestMetadata("argumentTypesNoinline.kt") + public void testArgumentTypesNoinline() throws Exception { + runTest("compiler/testData/codegen/box/callableReference/function/argumentTypesNoinline.kt"); + } + @Test @TestMetadata("booleanNotIntrinsic.kt") public void testBooleanNotIntrinsic() throws Exception { @@ -3237,6 +3243,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/callableReference/function/constructorFromTopLevelOneStringArg.kt"); } + @Test + @TestMetadata("dispatchReceiverType.kt") + public void testDispatchReceiverType() throws Exception { + runTest("compiler/testData/codegen/box/callableReference/function/dispatchReceiverType.kt"); + } + @Test @TestMetadata("enumValueOfMethod.kt") public void testEnumValueOfMethod() 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 46a582025c8..3b94800a85a 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -2782,6 +2782,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTest("compiler/testData/codegen/box/callableReference/function/argumentTypes.kt"); } + @TestMetadata("argumentTypesNoinline.kt") + public void testArgumentTypesNoinline() throws Exception { + runTest("compiler/testData/codegen/box/callableReference/function/argumentTypesNoinline.kt"); + } + @TestMetadata("booleanNotIntrinsic.kt") public void testBooleanNotIntrinsic() throws Exception { runTest("compiler/testData/codegen/box/callableReference/function/booleanNotIntrinsic.kt"); @@ -2837,6 +2842,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTest("compiler/testData/codegen/box/callableReference/function/constructorFromTopLevelOneStringArg.kt"); } + @TestMetadata("dispatchReceiverType.kt") + public void testDispatchReceiverType() throws Exception { + runTest("compiler/testData/codegen/box/callableReference/function/dispatchReceiverType.kt"); + } + @TestMetadata("enumValueOfMethod.kt") public void testEnumValueOfMethod() throws Exception { runTest("compiler/testData/codegen/box/callableReference/function/enumValueOfMethod.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 04c5f94f467..90e6b463654 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 @@ -1982,6 +1982,11 @@ public class IrJsCodegenBoxES6TestGenerated extends AbstractIrJsCodegenBoxES6Tes runTest("compiler/testData/codegen/box/callableReference/function/argumentTypes.kt"); } + @TestMetadata("argumentTypesNoinline.kt") + public void testArgumentTypesNoinline() throws Exception { + runTest("compiler/testData/codegen/box/callableReference/function/argumentTypesNoinline.kt"); + } + @TestMetadata("booleanNotIntrinsic.kt") public void testBooleanNotIntrinsic() throws Exception { runTest("compiler/testData/codegen/box/callableReference/function/booleanNotIntrinsic.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 034dedea3bb..5c70594e3c5 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 @@ -1982,6 +1982,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest { runTest("compiler/testData/codegen/box/callableReference/function/argumentTypes.kt"); } + @TestMetadata("argumentTypesNoinline.kt") + public void testArgumentTypesNoinline() throws Exception { + runTest("compiler/testData/codegen/box/callableReference/function/argumentTypesNoinline.kt"); + } + @TestMetadata("booleanNotIntrinsic.kt") public void testBooleanNotIntrinsic() throws Exception { runTest("compiler/testData/codegen/box/callableReference/function/booleanNotIntrinsic.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 063be31b933..d878b61273d 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 @@ -1982,6 +1982,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { runTest("compiler/testData/codegen/box/callableReference/function/argumentTypes.kt"); } + @TestMetadata("argumentTypesNoinline.kt") + public void testArgumentTypesNoinline() throws Exception { + runTest("compiler/testData/codegen/box/callableReference/function/argumentTypesNoinline.kt"); + } + @TestMetadata("booleanNotIntrinsic.kt") public void testBooleanNotIntrinsic() throws Exception { runTest("compiler/testData/codegen/box/callableReference/function/booleanNotIntrinsic.kt");