From 01507281a2cfc1e8dd40dc8da7b024b97a5ca4c4 Mon Sep 17 00:00:00 2001 From: Alexander Korepanov Date: Tue, 30 Aug 2022 12:58:48 +0200 Subject: [PATCH] [Common IR] Forward the extension receiver in the reified wrapper ^KT-53672 Fixed --- .../FirBlackBoxCodegenTestGenerated.java | 6 + ...ationsWithReifiedTypeParametersLowering.kt | 22 +++- ...icCallableReferenceWithReifiedTypeParam.kt | 114 ++++++++++++++++++ .../codegen/BlackBoxCodegenTestGenerated.java | 6 + .../IrBlackBoxCodegenTestGenerated.java | 6 + .../LightAnalysisModeTestGenerated.java | 5 + .../js/test/JsCodegenBoxTestGenerated.java | 6 + .../test/ir/IrJsCodegenBoxTestGenerated.java | 6 + .../IrCodegenBoxWasmTestGenerated.java | 5 + .../NativeCodegenBoxTestGenerated.java | 6 + 10 files changed, 179 insertions(+), 3 deletions(-) create mode 100644 compiler/testData/codegen/box/callableReference/function/genericCallableReferenceWithReifiedTypeParam.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 f4de4deb7ba..7a41000038e 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 @@ -4032,6 +4032,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT runTest("compiler/testData/codegen/box/callableReference/function/genericCallableReferenceArguments.kt"); } + @Test + @TestMetadata("genericCallableReferenceWithReifiedTypeParam.kt") + public void testGenericCallableReferenceWithReifiedTypeParam() throws Exception { + runTest("compiler/testData/codegen/box/callableReference/function/genericCallableReferenceWithReifiedTypeParam.kt"); + } + @Test @TestMetadata("genericCallableReferencesWithNullableTypes.kt") public void testGenericCallableReferencesWithNullableTypes() throws Exception { diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/WrapInlineDeclarationsWithReifiedTypeParametersLowering.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/WrapInlineDeclarationsWithReifiedTypeParametersLowering.kt index 04814b4745d..0bf4e1a0387 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/WrapInlineDeclarationsWithReifiedTypeParametersLowering.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/WrapInlineDeclarationsWithReifiedTypeParametersLowering.kt @@ -28,6 +28,7 @@ import org.jetbrains.kotlin.ir.util.typeSubstitutionMap import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.utils.addToStdlib.runIf // Replace callable reference on inline function with reified parameter // with callable reference on new non inline function with substituted types @@ -67,6 +68,15 @@ class WrapInlineDeclarationsWithReifiedTypeParametersLowering(val context: Backe }.apply { parent = container as IrDeclarationParent val irBuilder = context.createIrBuilder(symbol, SYNTHETIC_OFFSET, SYNTHETIC_OFFSET) + val forwardExtensionReceiverAsParam = owner.extensionReceiverParameter?.let { extensionReceiver -> + runIf(expression.extensionReceiver == null) { + addValueParameter( + extensionReceiver.name, + typeSubstitutor.substitute(extensionReceiver.type) + ) + true + } + } ?: false owner.valueParameters.forEach { valueParameter -> addValueParameter( valueParameter.name, @@ -80,9 +90,15 @@ class WrapInlineDeclarationsWithReifiedTypeParametersLowering(val context: Backe statements.add( irBuilder.irReturn( irBuilder.irCall(owner.symbol).also { call -> + val (extensionReceiver, forwardedParams) = if (forwardExtensionReceiverAsParam) { + irBuilder.irGet(valueParameters.first()) to valueParameters.subList(1, valueParameters.size) + } else { + expression.extensionReceiver to valueParameters + } + call.extensionReceiver = extensionReceiver call.dispatchReceiver = expression.dispatchReceiver - call.extensionReceiver = expression.extensionReceiver - valueParameters.forEachIndexed { index, valueParameter -> + + forwardedParams.forEachIndexed { index, valueParameter -> call.putValueArgument(index, irBuilder.irGet(valueParameter)) } for (i in 0 until expression.typeArgumentsCount) { @@ -110,4 +126,4 @@ class WrapInlineDeclarationsWithReifiedTypeParametersLowering(val context: Backe } }) } -} \ No newline at end of file +} diff --git a/compiler/testData/codegen/box/callableReference/function/genericCallableReferenceWithReifiedTypeParam.kt b/compiler/testData/codegen/box/callableReference/function/genericCallableReferenceWithReifiedTypeParam.kt new file mode 100644 index 00000000000..41b10e93a06 --- /dev/null +++ b/compiler/testData/codegen/box/callableReference/function/genericCallableReferenceWithReifiedTypeParam.kt @@ -0,0 +1,114 @@ +// WITH_STDLIB + +import kotlin.test.assertEquals + + +inline fun funNoArgs() = "OK" as? T + +fun testFunctionNoArgs() { + val callable: () -> String? = ::funNoArgs + assertEquals(callable(), "OK") +} + +inline fun funWithArgs(x: T, y: T) = x to y + +fun testFunctionWithArgs() { + val callable: (String, String) -> Pair = ::funWithArgs + assertEquals(callable("O", "K"), "O" to "K") +} + +inline fun funWithVarargs(vararg i: T) = i.toList() + +fun testFunctionWithVarargs() { + val callable: (Array) -> List = ::funWithVarargs + assertEquals(callable(arrayOf(1, 2, 3)), listOf(1, 2, 3)) +} + +inline fun T.funWithExtensionNoArgs() = this + +fun testFunctionWithExtensionNoArgs() { + val callable1 = String::funWithExtensionNoArgs + assertEquals(callable1("OK1"), "OK1") + + val callable2 = "OK2"::funWithExtensionNoArgs + assertEquals(callable2(), "OK2") + + val callable3 = callable1::funWithExtensionNoArgs + assertEquals(callable3()("OK3"), "OK3") + + val callable4 = with("OK4") { ::funWithExtensionNoArgs } + assertEquals(callable4(), "OK4") +} + +inline fun T.funWithExtensionAndArgs(x: Int, y: Int) = this to (x + y) + +fun testFunctionWithExtensionAndArgs() { + val callable1 = String::funWithExtensionAndArgs + assertEquals(callable1("OK1", 1, 2), "OK1" to 3) + + val callable2 = "OK2"::funWithExtensionAndArgs + assertEquals(callable2(3, 4), "OK2" to 7) + + val callable3 = callable1::funWithExtensionAndArgs + val (cb, s) = callable3(5, 6) + assertEquals(s, 11) + assertEquals(cb("OK3", 7, 8), "OK3" to 15) + + val callable4 = with("OK4") { ::funWithExtensionAndArgs } + assertEquals(callable4(9, 10), "OK4" to 19) +} + +inline fun T.funWithExtensionAndVarargs(vararg i: Int) = this to i.sum() + +fun testFunctionWithExtensionAndVararg() { + val callable1 = String::funWithExtensionAndVarargs + assertEquals(callable1("OK1", arrayOf(1, 2, 3).toIntArray()), "OK1" to 6) + + val callable2 = "OK2"::funWithExtensionAndVarargs + assertEquals(callable2(arrayOf(4, 5, 6).toIntArray()), "OK2" to 15) + + val callable3 = callable1::funWithExtensionAndVarargs + val (cb, s) = callable3(arrayOf(7, 8).toIntArray()) + assertEquals(s, 15) + assertEquals(cb("OK3", arrayOf(9, 10).toIntArray()), "OK3" to 19) + + val callable4 = with("OK4") { ::funWithExtensionAndVarargs } + assertEquals(callable4(arrayOf(11, 12).toIntArray()), "OK4" to 23) +} + +class TestClass(val s: String) { + inline fun classFunNoArgs() = s as? T + inline fun classFunWithArgs(x: T) = x to s + inline fun classFunWithVarargs(vararg i: T) = i.toList() to s +} + +fun testClassFunctionNoArgs() { + val callable: () -> String? = with(TestClass("OK1")) { ::classFunNoArgs } + assertEquals(callable(), "OK1") +} + +fun testClassFunctionWithArgs() { + val callable: (Int) -> Pair = with(TestClass("OK1")) { ::classFunWithArgs } + assertEquals(callable(1), 1 to "OK1") +} + +fun testClassFunctionWithVarargs() { + val callable: (Array) -> Pair, String> = with(TestClass("OK1")) { ::classFunWithVarargs } + assertEquals(callable(arrayOf(1, 2)), listOf(1, 2) to "OK1") +} + +fun box(): String { + testFunctionNoArgs() + testFunctionWithArgs() + testFunctionWithVarargs() + + testFunctionWithExtensionNoArgs() + testFunctionWithExtensionAndArgs() + testFunctionWithExtensionAndVararg() + + testClassFunctionNoArgs() + testClassFunctionWithArgs() + testClassFunctionWithVarargs() + + return "OK" +} 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 ea60211f29d..457f35c04b5 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 @@ -3918,6 +3918,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/callableReference/function/genericCallableReferenceArguments.kt"); } + @Test + @TestMetadata("genericCallableReferenceWithReifiedTypeParam.kt") + public void testGenericCallableReferenceWithReifiedTypeParam() throws Exception { + runTest("compiler/testData/codegen/box/callableReference/function/genericCallableReferenceWithReifiedTypeParam.kt"); + } + @Test @TestMetadata("genericCallableReferencesWithNullableTypes.kt") public void testGenericCallableReferencesWithNullableTypes() 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 f4608a1f5af..c1f16abafe9 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 @@ -4032,6 +4032,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/callableReference/function/genericCallableReferenceArguments.kt"); } + @Test + @TestMetadata("genericCallableReferenceWithReifiedTypeParam.kt") + public void testGenericCallableReferenceWithReifiedTypeParam() throws Exception { + runTest("compiler/testData/codegen/box/callableReference/function/genericCallableReferenceWithReifiedTypeParam.kt"); + } + @Test @TestMetadata("genericCallableReferencesWithNullableTypes.kt") public void testGenericCallableReferencesWithNullableTypes() 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 71d9c854e48..5a9de58dde1 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -3428,6 +3428,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTest("compiler/testData/codegen/box/callableReference/function/genericCallableReferenceArguments.kt"); } + @TestMetadata("genericCallableReferenceWithReifiedTypeParam.kt") + public void testGenericCallableReferenceWithReifiedTypeParam() throws Exception { + runTest("compiler/testData/codegen/box/callableReference/function/genericCallableReferenceWithReifiedTypeParam.kt"); + } + @TestMetadata("genericCallableReferencesWithNullableTypes.kt") public void testGenericCallableReferencesWithNullableTypes() throws Exception { runTest("compiler/testData/codegen/box/callableReference/function/genericCallableReferencesWithNullableTypes.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 e6f15859667..193deba923f 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 @@ -2736,6 +2736,12 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { runTest("compiler/testData/codegen/box/callableReference/function/genericCallableReferenceArguments.kt"); } + @Test + @TestMetadata("genericCallableReferenceWithReifiedTypeParam.kt") + public void testGenericCallableReferenceWithReifiedTypeParam() throws Exception { + runTest("compiler/testData/codegen/box/callableReference/function/genericCallableReferenceWithReifiedTypeParam.kt"); + } + @Test @TestMetadata("genericCallableReferencesWithNullableTypes.kt") public void testGenericCallableReferencesWithNullableTypes() throws Exception { 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 44b9dbcffd8..e42fb700b24 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 @@ -2784,6 +2784,12 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest { runTest("compiler/testData/codegen/box/callableReference/function/genericCallableReferenceArguments.kt"); } + @Test + @TestMetadata("genericCallableReferenceWithReifiedTypeParam.kt") + public void testGenericCallableReferenceWithReifiedTypeParam() throws Exception { + runTest("compiler/testData/codegen/box/callableReference/function/genericCallableReferenceWithReifiedTypeParam.kt"); + } + @Test @TestMetadata("genericCallableReferencesWithNullableTypes.kt") public void testGenericCallableReferencesWithNullableTypes() throws Exception { 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 c95d10b7410..8e73e4a08b4 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 @@ -2473,6 +2473,11 @@ public class IrCodegenBoxWasmTestGenerated extends AbstractIrCodegenBoxWasmTest runTest("compiler/testData/codegen/box/callableReference/function/genericCallableReferenceArguments.kt"); } + @TestMetadata("genericCallableReferenceWithReifiedTypeParam.kt") + public void testGenericCallableReferenceWithReifiedTypeParam() throws Exception { + runTest("compiler/testData/codegen/box/callableReference/function/genericCallableReferenceWithReifiedTypeParam.kt"); + } + @TestMetadata("genericCallableReferencesWithNullableTypes.kt") public void testGenericCallableReferencesWithNullableTypes() throws Exception { runTest("compiler/testData/codegen/box/callableReference/function/genericCallableReferencesWithNullableTypes.kt"); diff --git a/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/NativeCodegenBoxTestGenerated.java b/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/NativeCodegenBoxTestGenerated.java index ad9b0d57829..f327e127a0d 100644 --- a/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/NativeCodegenBoxTestGenerated.java +++ b/native/native.tests/tests-gen/org/jetbrains/kotlin/konan/blackboxtest/NativeCodegenBoxTestGenerated.java @@ -2850,6 +2850,12 @@ public class NativeCodegenBoxTestGenerated extends AbstractNativeCodegenBoxTest runTest("compiler/testData/codegen/box/callableReference/function/genericCallableReferenceArguments.kt"); } + @Test + @TestMetadata("genericCallableReferenceWithReifiedTypeParam.kt") + public void testGenericCallableReferenceWithReifiedTypeParam() throws Exception { + runTest("compiler/testData/codegen/box/callableReference/function/genericCallableReferenceWithReifiedTypeParam.kt"); + } + @Test @TestMetadata("genericCallableReferencesWithNullableTypes.kt") public void testGenericCallableReferencesWithNullableTypes() throws Exception {