From e2099a030770b7551504c9885faa6ccb606d2f42 Mon Sep 17 00:00:00 2001 From: Denis Zharkov Date: Thu, 12 Nov 2020 11:29:20 +0300 Subject: [PATCH] FIR: Fix false-positive successful resolution of call with lambda receiver Do not try to integrate/postpone receiver expression to the base system Receiver should be resolved independently anyway --- .../callResolution/lambdaAsReceiver.kt | 14 +++++++++++++ .../callResolution/lambdaAsReceiver.txt | 21 +++++++++++++++++++ .../fir/FirDiagnosticsTestGenerated.java | 5 +++++ ...DiagnosticsWithLightTreeTestGenerated.java | 5 +++++ ...TouchedTilContractsPhaseTestGenerated.java | 5 +++++ .../fir/resolve/calls/ResolutionStages.kt | 3 +-- 6 files changed, 51 insertions(+), 2 deletions(-) create mode 100644 compiler/fir/analysis-tests/testData/resolve/callResolution/lambdaAsReceiver.kt create mode 100644 compiler/fir/analysis-tests/testData/resolve/callResolution/lambdaAsReceiver.txt diff --git a/compiler/fir/analysis-tests/testData/resolve/callResolution/lambdaAsReceiver.kt b/compiler/fir/analysis-tests/testData/resolve/callResolution/lambdaAsReceiver.kt new file mode 100644 index 00000000000..543f908a55b --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/callResolution/lambdaAsReceiver.kt @@ -0,0 +1,14 @@ +fun (() -> String).foo() {} +fun String.foo() {} + +fun String.bar() {} + +fun main1() { + { "" }.foo() + "".foo() +} + +fun main2() { + { "" }.bar() + "".bar() +} diff --git a/compiler/fir/analysis-tests/testData/resolve/callResolution/lambdaAsReceiver.txt b/compiler/fir/analysis-tests/testData/resolve/callResolution/lambdaAsReceiver.txt new file mode 100644 index 00000000000..021cd8e6ff4 --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolve/callResolution/lambdaAsReceiver.txt @@ -0,0 +1,21 @@ +FILE: lambdaAsReceiver.kt + public final fun R|() -> kotlin/String|.foo(): R|kotlin/Unit| { + } + public final fun R|kotlin/String|.foo(): R|kotlin/Unit| { + } + public final fun R|kotlin/String|.bar(): R|kotlin/Unit| { + } + public final fun main1(): R|kotlin/Unit| { + fun (): R|kotlin/String| { + ^ String() + } + .R|/foo|() + String().R|/foo|() + } + public final fun main2(): R|kotlin/Unit| { + fun (): R|kotlin/String| { + ^ String() + } + .#() + String().R|/bar|() + } diff --git a/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirDiagnosticsTestGenerated.java b/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirDiagnosticsTestGenerated.java index 857fe390915..87b998865de 100644 --- a/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirDiagnosticsTestGenerated.java +++ b/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirDiagnosticsTestGenerated.java @@ -724,6 +724,11 @@ public class FirDiagnosticsTestGenerated extends AbstractFirDiagnosticsTest { runTest("compiler/fir/analysis-tests/testData/resolve/callResolution/invokeWithReceiverAndArgument.kt"); } + @TestMetadata("lambdaAsReceiver.kt") + public void testLambdaAsReceiver() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/callResolution/lambdaAsReceiver.kt"); + } + @TestMetadata("objectInvoke.kt") public void testObjectInvoke() throws Exception { runTest("compiler/fir/analysis-tests/testData/resolve/callResolution/objectInvoke.kt"); diff --git a/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirDiagnosticsWithLightTreeTestGenerated.java b/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirDiagnosticsWithLightTreeTestGenerated.java index e8917ad8388..c974f775714 100644 --- a/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirDiagnosticsWithLightTreeTestGenerated.java +++ b/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/FirDiagnosticsWithLightTreeTestGenerated.java @@ -724,6 +724,11 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos runTest("compiler/fir/analysis-tests/testData/resolve/callResolution/invokeWithReceiverAndArgument.kt"); } + @TestMetadata("lambdaAsReceiver.kt") + public void testLambdaAsReceiver() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/callResolution/lambdaAsReceiver.kt"); + } + @TestMetadata("objectInvoke.kt") public void testObjectInvoke() throws Exception { runTest("compiler/fir/analysis-tests/testData/resolve/callResolution/objectInvoke.kt"); diff --git a/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/LazyBodyIsNotTouchedTilContractsPhaseTestGenerated.java b/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/LazyBodyIsNotTouchedTilContractsPhaseTestGenerated.java index 33f2005642a..0e32f18e276 100644 --- a/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/LazyBodyIsNotTouchedTilContractsPhaseTestGenerated.java +++ b/compiler/fir/analysis-tests/tests/org/jetbrains/kotlin/fir/LazyBodyIsNotTouchedTilContractsPhaseTestGenerated.java @@ -724,6 +724,11 @@ public class LazyBodyIsNotTouchedTilContractsPhaseTestGenerated extends Abstract runTest("compiler/fir/analysis-tests/testData/resolve/callResolution/invokeWithReceiverAndArgument.kt"); } + @TestMetadata("lambdaAsReceiver.kt") + public void testLambdaAsReceiver() throws Exception { + runTest("compiler/fir/analysis-tests/testData/resolve/callResolution/lambdaAsReceiver.kt"); + } + @TestMetadata("objectInvoke.kt") public void testObjectInvoke() throws Exception { runTest("compiler/fir/analysis-tests/testData/resolve/callResolution/objectInvoke.kt"); diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionStages.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionStages.kt index 905b6f04f7c..36d405d9dd6 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionStages.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionStages.kt @@ -115,11 +115,10 @@ internal sealed class CheckReceivers : ResolutionStage() { explicitReceiverKind.shouldBeCheckedAgainstExplicit() && !explicitReceiverExpression.isSuperReferenceExpression() ) { - candidate.resolveArgumentExpression( + candidate.resolvePlainExpressionArgument( candidate.csBuilder, argument = explicitReceiverExpression, expectedType = candidate.substitutor.substituteOrSelf(expectedReceiverType), - expectedTypeRef = explicitReceiverExpression.typeRef, sink = sink, context = context, isReceiver = true,