From d7d7620db295a7b8ad153f13fc9253c2ee52f7ab Mon Sep 17 00:00:00 2001 From: Dmitriy Novozhilov Date: Fri, 31 Mar 2023 13:45:57 +0300 Subject: [PATCH] [FIR2IR] Correctly calculate signature for non-dynamic calls on dynamic receiver If dispatch receiver is dynamic and call on it is not dynamic that means that this call was resolved to some specific declaration because of smartcast. So we should use original type of this declaration as dispatch receiver during calculation of IdSignature instead of Any (which came from dynamic type). Otherwise we will have two different signatures for the same member declaration ^KT-57682 Fixed --- .../jetbrains/kotlin/fir/backend/ConversionUtils.kt | 11 +++++++++-- .../codegen/box/smartCasts/smartcastOnDynamic.kt | 13 +++++++++++++ .../js/test/fir/FirJsCodegenBoxTestGenerated.java | 6 ++++++ .../js/test/ir/IrJsCodegenBoxTestGenerated.java | 6 ++++++ .../js/test/ir/IrJsES6CodegenBoxTestGenerated.java | 6 ++++++ 5 files changed, 40 insertions(+), 2 deletions(-) create mode 100644 compiler/testData/codegen/box/smartCasts/smartcastOnDynamic.kt diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/ConversionUtils.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/ConversionUtils.kt index 0eb9184d020..1c91ab3482b 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/ConversionUtils.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/ConversionUtils.kt @@ -229,7 +229,14 @@ private fun FirCallableSymbol<*>.toSymbolForCall( } // Member fake override or bound callable reference dispatchReceiver !is FirNoReceiverExpression -> { - dispatchReceiver.typeRef.coneType.let { it.findClassRepresentation(it, declarationStorage.session) } + val callSiteDispatchReceiverType = dispatchReceiver.typeRef.coneType + val declarationSiteDispatchReceiverType = dispatchReceiverType + val type = if (callSiteDispatchReceiverType is ConeDynamicType && declarationSiteDispatchReceiverType != null) { + declarationSiteDispatchReceiverType + } else { + callSiteDispatchReceiverType + } + type.findClassRepresentation(type, declarationStorage.session) } // Unbound callable reference to member (non-extension) isReference && fir.receiverParameter == null -> { @@ -752,4 +759,4 @@ fun FirCallableDeclaration.contextReceiversForFunctionOrContainingProperty(): Li fun IrActualizationResult?.extractFirDeclarations(): Set? { return this?.actualizedExpectDeclarations?.mapNotNullTo(mutableSetOf()) { ((it as IrMetadataSourceOwner).metadata as FirMetadataSource).fir } -} \ No newline at end of file +} diff --git a/compiler/testData/codegen/box/smartCasts/smartcastOnDynamic.kt b/compiler/testData/codegen/box/smartCasts/smartcastOnDynamic.kt new file mode 100644 index 00000000000..20f9d815559 --- /dev/null +++ b/compiler/testData/codegen/box/smartCasts/smartcastOnDynamic.kt @@ -0,0 +1,13 @@ +// TARGET_BACKEND: JS_IR +// ISSUE: KT-57682 +fun test_1(x: String) = x.length + +fun test_2(x: dynamic): Int = when (x) { + is String -> x.length + else -> x.something +} + +fun box(): String { + val result = test_1("a") + test_2("ab") + return if (result == 3) "OK" else "fail" +} diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/fir/FirJsCodegenBoxTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/fir/FirJsCodegenBoxTestGenerated.java index 7523c434fa7..736e6f3a499 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/fir/FirJsCodegenBoxTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/fir/FirJsCodegenBoxTestGenerated.java @@ -35055,6 +35055,12 @@ public class FirJsCodegenBoxTestGenerated extends AbstractFirJsCodegenBoxTest { runTest("compiler/testData/codegen/box/smartCasts/smartCastInsideIf.kt"); } + @Test + @TestMetadata("smartcastOnDynamic.kt") + public void testSmartcastOnDynamic() throws Exception { + runTest("compiler/testData/codegen/box/smartCasts/smartcastOnDynamic.kt"); + } + @Test @TestMetadata("whenSmartCast.kt") public void testWhenSmartCast() 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 7900ea46ea1..2eaa51c2186 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 @@ -35055,6 +35055,12 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest { runTest("compiler/testData/codegen/box/smartCasts/smartCastInsideIf.kt"); } + @Test + @TestMetadata("smartcastOnDynamic.kt") + public void testSmartcastOnDynamic() throws Exception { + runTest("compiler/testData/codegen/box/smartCasts/smartcastOnDynamic.kt"); + } + @Test @TestMetadata("whenSmartCast.kt") public void testWhenSmartCast() throws Exception { diff --git a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrJsES6CodegenBoxTestGenerated.java b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrJsES6CodegenBoxTestGenerated.java index 7762c2a8dbc..2efe308ced9 100644 --- a/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrJsES6CodegenBoxTestGenerated.java +++ b/js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrJsES6CodegenBoxTestGenerated.java @@ -35055,6 +35055,12 @@ public class IrJsES6CodegenBoxTestGenerated extends AbstractIrJsES6CodegenBoxTes runTest("compiler/testData/codegen/box/smartCasts/smartCastInsideIf.kt"); } + @Test + @TestMetadata("smartcastOnDynamic.kt") + public void testSmartcastOnDynamic() throws Exception { + runTest("compiler/testData/codegen/box/smartCasts/smartcastOnDynamic.kt"); + } + @Test @TestMetadata("whenSmartCast.kt") public void testWhenSmartCast() throws Exception {