From b1b89e6f5f8d703654dc263b1832de4697aaca00 Mon Sep 17 00:00:00 2001 From: "Denis.Zharkov" Date: Tue, 26 Jan 2021 10:28:07 +0300 Subject: [PATCH] FIR2IR: Fix smart-cast approximation implicit receiver Previously, it was always cast to the first type of smart cast variants list independently of callee symbol that might be present in the member scope of a different type --- .../FirBlackBoxCodegenTestGenerated.java | 6 ++++++ .../kotlin/fir/backend/Fir2IrVisitor.kt | 2 +- .../generators/CallAndReferenceGenerator.kt | 7 +++---- .../box/smartCasts/complexImplicitReceiver.kt | 17 +++++++++++++++++ .../codegen/BlackBoxCodegenTestGenerated.java | 6 ++++++ .../codegen/IrBlackBoxCodegenTestGenerated.java | 6 ++++++ .../codegen/LightAnalysisModeTestGenerated.java | 5 +++++ .../IrJsCodegenBoxES6TestGenerated.java | 5 +++++ .../semantics/IrJsCodegenBoxTestGenerated.java | 5 +++++ .../semantics/JsCodegenBoxTestGenerated.java | 5 +++++ .../IrCodegenBoxWasmTestGenerated.java | 5 +++++ 11 files changed, 64 insertions(+), 5 deletions(-) create mode 100644 compiler/testData/codegen/box/smartCasts/complexImplicitReceiver.kt diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java index 9e13e9c94d4..bb51c956b4c 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java @@ -34894,6 +34894,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/smartCasts"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true); } + @Test + @TestMetadata("complexImplicitReceiver.kt") + public void testComplexImplicitReceiver() throws Exception { + runTest("compiler/testData/codegen/box/smartCasts/complexImplicitReceiver.kt"); + } + @Test @TestMetadata("falseSmartCast.kt") public void testFalseSmartCast() throws Exception { diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrVisitor.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrVisitor.kt index 8427a0e5a48..5f0f3703d44 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrVisitor.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrVisitor.kt @@ -470,7 +470,7 @@ class Fir2IrVisitor( } } - private fun convertToIrReceiverExpression( + internal fun convertToIrReceiverExpression( expression: FirExpression?, calleeReference: FirReference, callableReferenceAccess: FirCallableReferenceAccess? = null 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 fa4f3b87b31..4657a143edf 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 @@ -713,10 +713,9 @@ class CallAndReferenceGenerator( if (firReceiver == explicitReceiver) { return explicitReceiverExpression } - if (firReceiver is FirResolvedQualifier) { - return convertToGetObject(firReceiver, this as? FirCallableReferenceAccess) - } - return firReceiver.takeIf { it !is FirNoReceiverExpression }?.let { visitor.convertToIrExpression(it) } + + return firReceiver.takeIf { it !is FirNoReceiverExpression } + ?.let { visitor.convertToIrReceiverExpression(it, calleeReference, this as? FirCallableReferenceAccess) } ?: explicitReceiverExpression ?: run { if (this is FirCallableReferenceAccess) return null diff --git a/compiler/testData/codegen/box/smartCasts/complexImplicitReceiver.kt b/compiler/testData/codegen/box/smartCasts/complexImplicitReceiver.kt new file mode 100644 index 00000000000..227e28633d2 --- /dev/null +++ b/compiler/testData/codegen/box/smartCasts/complexImplicitReceiver.kt @@ -0,0 +1,17 @@ +interface Bound +interface CompilerPhase + +private class CompositePhase( + val foo: String +) : CompilerPhase + +@Suppress("UNCHECKED_CAST") +fun CompilerPhase.bar(): String { + this as CompilerPhase + val ok = if (this is CompositePhase) foo + "K" else "fail" + return ok +} + +fun box(): String { + return CompositePhase("O").bar() +} 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 0f6898b9cc1..50d4043833c 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 @@ -35094,6 +35094,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/smartCasts"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true); } + @Test + @TestMetadata("complexImplicitReceiver.kt") + public void testComplexImplicitReceiver() throws Exception { + runTest("compiler/testData/codegen/box/smartCasts/complexImplicitReceiver.kt"); + } + @Test @TestMetadata("falseSmartCast.kt") public void testFalseSmartCast() 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 81333c097ea..b49c31ba0e2 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 @@ -34894,6 +34894,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/smartCasts"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true); } + @Test + @TestMetadata("complexImplicitReceiver.kt") + public void testComplexImplicitReceiver() throws Exception { + runTest("compiler/testData/codegen/box/smartCasts/complexImplicitReceiver.kt"); + } + @Test @TestMetadata("falseSmartCast.kt") public void testFalseSmartCast() 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 27f9022de03..471512c6f8d 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -28666,6 +28666,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/smartCasts"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true); } + @TestMetadata("complexImplicitReceiver.kt") + public void testComplexImplicitReceiver() throws Exception { + runTest("compiler/testData/codegen/box/smartCasts/complexImplicitReceiver.kt"); + } + @TestMetadata("falseSmartCast.kt") public void testFalseSmartCast() throws Exception { runTest("compiler/testData/codegen/box/smartCasts/falseSmartCast.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 360ee393f14..142c74c6815 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 @@ -24792,6 +24792,11 @@ public class IrJsCodegenBoxES6TestGenerated extends AbstractIrJsCodegenBoxES6Tes KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/smartCasts"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR_ES6, true); } + @TestMetadata("complexImplicitReceiver.kt") + public void testComplexImplicitReceiver() throws Exception { + runTest("compiler/testData/codegen/box/smartCasts/complexImplicitReceiver.kt"); + } + @TestMetadata("falseSmartCast.kt") public void testFalseSmartCast() throws Exception { runTest("compiler/testData/codegen/box/smartCasts/falseSmartCast.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 9c921643b65..71a0780d19b 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 @@ -24792,6 +24792,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest { KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/smartCasts"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR, true); } + @TestMetadata("complexImplicitReceiver.kt") + public void testComplexImplicitReceiver() throws Exception { + runTest("compiler/testData/codegen/box/smartCasts/complexImplicitReceiver.kt"); + } + @TestMetadata("falseSmartCast.kt") public void testFalseSmartCast() throws Exception { runTest("compiler/testData/codegen/box/smartCasts/falseSmartCast.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 52787c0d968..b804a2cbcc4 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 @@ -24757,6 +24757,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/smartCasts"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS, true); } + @TestMetadata("complexImplicitReceiver.kt") + public void testComplexImplicitReceiver() throws Exception { + runTest("compiler/testData/codegen/box/smartCasts/complexImplicitReceiver.kt"); + } + @TestMetadata("falseSmartCast.kt") public void testFalseSmartCast() throws Exception { runTest("compiler/testData/codegen/box/smartCasts/falseSmartCast.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 99f5351fe67..e991db16c9f 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 @@ -13261,6 +13261,11 @@ public class IrCodegenBoxWasmTestGenerated extends AbstractIrCodegenBoxWasmTest KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/smartCasts"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.WASM, true); } + @TestMetadata("complexImplicitReceiver.kt") + public void testComplexImplicitReceiver() throws Exception { + runTest("compiler/testData/codegen/box/smartCasts/complexImplicitReceiver.kt"); + } + @TestMetadata("falseSmartCast.kt") public void testFalseSmartCast() throws Exception { runTest("compiler/testData/codegen/box/smartCasts/falseSmartCast.kt");