From dbd28142d0ee48436e38a55822d6ad28348f6e6b Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Thu, 30 Sep 2021 01:31:50 +0200 Subject: [PATCH] Fix callable reference adaptation for vararg in fake override `mappedVarargElements` are populated with parameters from `argumentMapping`, which is computed using `ArgumentsToParametersMapper` which calls `original` on all value parameters (see ArgumentsToParametersMapper.kt:136). So the code that adds empty lists for unassigned vararg parameters should also call `original`. Otherwise, in the added test, we ended up with two arguments for the parameter `s` in `id(::base1)`, one for `Base.s` containing the correct value, and another for `Derived.s` containing the empty list. Psi2ir took the last one, which resulted in empty array being passed to the vararg parameter. Note that all of this is caused by the fact that `original` of a fake override parameter is the parameter of the base function. This seems suspicious because `original` of a fake override _function_ is that fake override itself (NOT the base function), but this would probably be very risky to change at this point. #KT-48835 Fixed --- .../FirBlackBoxCodegenTestGenerated.java | 6 +++ .../CallableReferencesCandidateFactory.kt | 5 +-- .../adaptedReferences/varargFromBaseClass.kt | 42 +++++++++++++++++++ .../codegen/BlackBoxCodegenTestGenerated.java | 6 +++ .../IrBlackBoxCodegenTestGenerated.java | 6 +++ .../LightAnalysisModeTestGenerated.java | 5 +++ .../IrJsCodegenBoxES6TestGenerated.java | 5 +++ .../IrJsCodegenBoxTestGenerated.java | 5 +++ .../semantics/JsCodegenBoxTestGenerated.java | 5 +++ .../IrCodegenBoxWasmTestGenerated.java | 5 +++ 10 files changed, 87 insertions(+), 3 deletions(-) create mode 100644 compiler/testData/codegen/box/callableReference/adaptedReferences/varargFromBaseClass.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 d0db09728b8..373634a319e 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 @@ -3055,6 +3055,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT runTest("compiler/testData/codegen/box/callableReference/adaptedReferences/unboundReferences.kt"); } + @Test + @TestMetadata("varargFromBaseClass.kt") + public void testVarargFromBaseClass() throws Exception { + runTest("compiler/testData/codegen/box/callableReference/adaptedReferences/varargFromBaseClass.kt"); + } + @Test @TestMetadata("varargViewedAsArray.kt") public void testVarargViewedAsArray() throws Exception { diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/CallableReferencesCandidateFactory.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/CallableReferencesCandidateFactory.kt index d4353436707..0867ab8cdff 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/CallableReferencesCandidateFactory.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/CallableReferencesCandidateFactory.kt @@ -9,7 +9,6 @@ import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.ReflectionTypes import org.jetbrains.kotlin.builtins.isFunctionType import org.jetbrains.kotlin.builtins.isSuspendFunctionType -import org.jetbrains.kotlin.config.ApiVersion import org.jetbrains.kotlin.config.LanguageFeature import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.annotations.Annotations @@ -218,8 +217,8 @@ class CallableReferencesCandidateFactory( } for (valueParameter in descriptor.valueParameters) { - if (valueParameter.isVararg && valueParameter !in mappedArguments) { - mappedArguments[valueParameter] = ResolvedCallArgument.VarargArgument(emptyList()) + if (valueParameter.isVararg) { + mappedArguments.putIfAbsent(valueParameter.original, ResolvedCallArgument.VarargArgument(emptyList())) } } diff --git a/compiler/testData/codegen/box/callableReference/adaptedReferences/varargFromBaseClass.kt b/compiler/testData/codegen/box/callableReference/adaptedReferences/varargFromBaseClass.kt new file mode 100644 index 00000000000..01b78652c82 --- /dev/null +++ b/compiler/testData/codegen/box/callableReference/adaptedReferences/varargFromBaseClass.kt @@ -0,0 +1,42 @@ +var result = "" + +abstract class Base { + fun base1(vararg s: String) { + if (s.size != 1) throw AssertionError("Fail size: ${s.size}") + result += s[0] + } + + fun base2(s: String) { + result += s + } +} + +fun id(f: (String) -> Unit): (String) -> Unit = f + +class Derived : Base() { + init { + id { base1(it) }.invoke("1") + id(::base1).invoke("2") + id { base2(it) }.invoke("3") + id(::base2).invoke("4") + + id { derived1(it) }.invoke("5") + id(::derived1).invoke("6") + id { derived2(it) }.invoke("7") + id(::derived2).invoke("8") + } + + private fun derived1(vararg s: String) { + if (s.size != 1) throw AssertionError("Fail size: ${s.size}") + result += s[0] + } + + private fun derived2(s: String) { + result += s + } +} + +fun box(): String { + Derived() + return if (result == "12345678") "OK" else "Fail result: $result" +} 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 2e320f53297..ea2249f8147 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 @@ -2983,6 +2983,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/callableReference/adaptedReferences/unboundReferences.kt"); } + @Test + @TestMetadata("varargFromBaseClass.kt") + public void testVarargFromBaseClass() throws Exception { + runTest("compiler/testData/codegen/box/callableReference/adaptedReferences/varargFromBaseClass.kt"); + } + @Test @TestMetadata("varargViewedAsArray.kt") public void testVarargViewedAsArray() 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 d5ae1fb6828..f9f6b233b55 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 @@ -3055,6 +3055,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/callableReference/adaptedReferences/unboundReferences.kt"); } + @Test + @TestMetadata("varargFromBaseClass.kt") + public void testVarargFromBaseClass() throws Exception { + runTest("compiler/testData/codegen/box/callableReference/adaptedReferences/varargFromBaseClass.kt"); + } + @Test @TestMetadata("varargViewedAsArray.kt") public void testVarargViewedAsArray() 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 907ea2ee12d..f7df6efcfd9 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -2616,6 +2616,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTest("compiler/testData/codegen/box/callableReference/adaptedReferences/unboundReferences.kt"); } + @TestMetadata("varargFromBaseClass.kt") + public void testVarargFromBaseClass() throws Exception { + runTest("compiler/testData/codegen/box/callableReference/adaptedReferences/varargFromBaseClass.kt"); + } + @TestMetadata("varargViewedAsArray.kt") public void testVarargViewedAsArray() throws Exception { runTest("compiler/testData/codegen/box/callableReference/adaptedReferences/varargViewedAsArray.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 b55b328b990..e957e8350b4 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 @@ -1816,6 +1816,11 @@ public class IrJsCodegenBoxES6TestGenerated extends AbstractIrJsCodegenBoxES6Tes runTest("compiler/testData/codegen/box/callableReference/adaptedReferences/unboundReferences.kt"); } + @TestMetadata("varargFromBaseClass.kt") + public void testVarargFromBaseClass() throws Exception { + runTest("compiler/testData/codegen/box/callableReference/adaptedReferences/varargFromBaseClass.kt"); + } + @TestMetadata("varargViewedAsArray.kt") public void testVarargViewedAsArray() throws Exception { runTest("compiler/testData/codegen/box/callableReference/adaptedReferences/varargViewedAsArray.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 2964536e060..fc912f04864 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 @@ -1816,6 +1816,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest { runTest("compiler/testData/codegen/box/callableReference/adaptedReferences/unboundReferences.kt"); } + @TestMetadata("varargFromBaseClass.kt") + public void testVarargFromBaseClass() throws Exception { + runTest("compiler/testData/codegen/box/callableReference/adaptedReferences/varargFromBaseClass.kt"); + } + @TestMetadata("varargViewedAsArray.kt") public void testVarargViewedAsArray() throws Exception { runTest("compiler/testData/codegen/box/callableReference/adaptedReferences/varargViewedAsArray.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 4c5735b6abb..543d5b5acff 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 @@ -1781,6 +1781,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { runTest("compiler/testData/codegen/box/callableReference/adaptedReferences/unboundReferences.kt"); } + @TestMetadata("varargFromBaseClass.kt") + public void testVarargFromBaseClass() throws Exception { + runTest("compiler/testData/codegen/box/callableReference/adaptedReferences/varargFromBaseClass.kt"); + } + @TestMetadata("varargViewedAsArray.kt") public void testVarargViewedAsArray() throws Exception { runTest("compiler/testData/codegen/box/callableReference/adaptedReferences/varargViewedAsArray.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 9564a3fd2d8..e93969e538a 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 @@ -1616,6 +1616,11 @@ public class IrCodegenBoxWasmTestGenerated extends AbstractIrCodegenBoxWasmTest runTest("compiler/testData/codegen/box/callableReference/adaptedReferences/unboundReferences.kt"); } + @TestMetadata("varargFromBaseClass.kt") + public void testVarargFromBaseClass() throws Exception { + runTest("compiler/testData/codegen/box/callableReference/adaptedReferences/varargFromBaseClass.kt"); + } + @TestMetadata("varargViewedAsArray.kt") public void testVarargViewedAsArray() throws Exception { runTest("compiler/testData/codegen/box/callableReference/adaptedReferences/varargViewedAsArray.kt");