K2: Fix IAE at Candidate.updateSourcesOfReceivers inside PCLA lambda

Previously, it was failing at line
(resolvedReceiver?.toReference(session) as? FirNamedReferenceWithCandidate)?.candidate?.updateSourcesOfReceivers()

But this line was mostly incorrect because in case of `a.b()` call,
which is resolved to `a.b.invoke()`, `resolvedReceiver` is pointing to
`a` instead of obviously expected `a.b`.

The fix with using `candidate.callInfo.explicitReceiver` doesn't help
either because the candidate of that receiver is always completed at
that stage (so no Candidate there).

The only case when the candidate was still there is PCLA because
 in that case we explicitly don't fully complete even receiver
expressions.
(see docs/fir/pcla.md)

The idea of the fix is moving the call of `updateSourcesOfReceivers`
for invoke property receiver to the place just before the candidate
is being converted to the resolved reference
(i.e., the candidate is being lost)

^KT-66148 Fixed
This commit is contained in:
Denis.Zharkov
2024-03-05 15:43:10 +01:00
committed by Space Team
parent ae9c9b051f
commit b7129f78a3
30 changed files with 206 additions and 6 deletions
@@ -17807,6 +17807,12 @@ public class DiagnosticCompilerTestFE10TestdataTestGenerated extends AbstractDia
runTest("compiler/testData/diagnostics/tests/inference/builderInference/overloadResolutionByLambdaReturnTypeInsideBI.kt");
}
@Test
@TestMetadata("propertyInvokeInsidePCLALambda.kt")
public void testPropertyInvokeInsidePCLALambda() {
runTest("compiler/testData/diagnostics/tests/inference/builderInference/propertyInvokeInsidePCLALambda.kt");
}
@Test
@TestMetadata("propertySubstitution.kt")
public void testPropertySubstitution() {
@@ -3554,6 +3554,12 @@ public class LLFirBlackBoxCodegenBasedTestGenerated extends AbstractLLFirBlackBo
runTest("compiler/testData/codegen/box/builderInference/posptonedPCLACallInsideStringInterpolation.kt");
}
@Test
@TestMetadata("propertyInvokeInsidePCLALambda.kt")
public void testPropertyInvokeInsidePCLALambda() {
runTest("compiler/testData/codegen/box/builderInference/propertyInvokeInsidePCLALambda.kt");
}
@Test
@TestMetadata("receiverUsesOuterTVButReturnTypeIsProper.kt")
public void testReceiverUsesOuterTVButReturnTypeIsProper() {
@@ -17807,6 +17807,12 @@ public class LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated
runTest("compiler/testData/diagnostics/tests/inference/builderInference/overloadResolutionByLambdaReturnTypeInsideBI.kt");
}
@Test
@TestMetadata("propertyInvokeInsidePCLALambda.kt")
public void testPropertyInvokeInsidePCLALambda() {
runTest("compiler/testData/diagnostics/tests/inference/builderInference/propertyInvokeInsidePCLALambda.kt");
}
@Test
@TestMetadata("propertySubstitution.kt")
public void testPropertySubstitution() {
@@ -3554,6 +3554,12 @@ public class LLFirReversedBlackBoxCodegenBasedTestGenerated extends AbstractLLFi
runTest("compiler/testData/codegen/box/builderInference/posptonedPCLACallInsideStringInterpolation.kt");
}
@Test
@TestMetadata("propertyInvokeInsidePCLALambda.kt")
public void testPropertyInvokeInsidePCLALambda() {
runTest("compiler/testData/codegen/box/builderInference/propertyInvokeInsidePCLALambda.kt");
}
@Test
@TestMetadata("receiverUsesOuterTVButReturnTypeIsProper.kt")
public void testReceiverUsesOuterTVButReturnTypeIsProper() {
@@ -17801,6 +17801,12 @@ public class FirLightTreeOldFrontendDiagnosticsTestGenerated extends AbstractFir
runTest("compiler/testData/diagnostics/tests/inference/builderInference/overloadResolutionByLambdaReturnTypeInsideBI.kt");
}
@Test
@TestMetadata("propertyInvokeInsidePCLALambda.kt")
public void testPropertyInvokeInsidePCLALambda() {
runTest("compiler/testData/diagnostics/tests/inference/builderInference/propertyInvokeInsidePCLALambda.kt");
}
@Test
@TestMetadata("propertySubstitution.kt")
public void testPropertySubstitution() {
@@ -17807,6 +17807,12 @@ public class FirPsiOldFrontendDiagnosticsTestGenerated extends AbstractFirPsiDia
runTest("compiler/testData/diagnostics/tests/inference/builderInference/overloadResolutionByLambdaReturnTypeInsideBI.kt");
}
@Test
@TestMetadata("propertyInvokeInsidePCLALambda.kt")
public void testPropertyInvokeInsidePCLALambda() {
runTest("compiler/testData/diagnostics/tests/inference/builderInference/propertyInvokeInsidePCLALambda.kt");
}
@Test
@TestMetadata("propertySubstitution.kt")
public void testPropertySubstitution() {
@@ -3537,6 +3537,12 @@ public class FirLightTreeBlackBoxCodegenTestGenerated extends AbstractFirLightTr
runTest("compiler/testData/codegen/box/builderInference/posptonedPCLACallInsideStringInterpolation.kt");
}
@Test
@TestMetadata("propertyInvokeInsidePCLALambda.kt")
public void testPropertyInvokeInsidePCLALambda() {
runTest("compiler/testData/codegen/box/builderInference/propertyInvokeInsidePCLALambda.kt");
}
@Test
@TestMetadata("receiverUsesOuterTVButReturnTypeIsProper.kt")
public void testReceiverUsesOuterTVButReturnTypeIsProper() {
@@ -3537,6 +3537,12 @@ public class FirLightTreeBlackBoxCodegenWithFir2IrFakeOverrideGeneratorTestGener
runTest("compiler/testData/codegen/box/builderInference/posptonedPCLACallInsideStringInterpolation.kt");
}
@Test
@TestMetadata("propertyInvokeInsidePCLALambda.kt")
public void testPropertyInvokeInsidePCLALambda() {
runTest("compiler/testData/codegen/box/builderInference/propertyInvokeInsidePCLALambda.kt");
}
@Test
@TestMetadata("receiverUsesOuterTVButReturnTypeIsProper.kt")
public void testReceiverUsesOuterTVButReturnTypeIsProper() {
@@ -3537,6 +3537,12 @@ public class FirPsiBlackBoxCodegenTestGenerated extends AbstractFirPsiBlackBoxCo
runTest("compiler/testData/codegen/box/builderInference/posptonedPCLACallInsideStringInterpolation.kt");
}
@Test
@TestMetadata("propertyInvokeInsidePCLALambda.kt")
public void testPropertyInvokeInsidePCLALambda() {
runTest("compiler/testData/codegen/box/builderInference/propertyInvokeInsidePCLALambda.kt");
}
@Test
@TestMetadata("receiverUsesOuterTVButReturnTypeIsProper.kt")
public void testReceiverUsesOuterTVButReturnTypeIsProper() {
@@ -111,13 +111,10 @@ class FirCallResolver(
resolvedReceiver.replaceResolvedToCompanionObject(candidate.isFromCompanionObjectTypeScope)
}
candidate?.updateSourcesOfReceivers()
// We need desugaring
val resultFunctionCall = if (candidate != null && candidate.callInfo != result.info) {
// This branch support case for the call of the type `a.invoke()`
// 1. Handle candidate for `a`
(resolvedReceiver?.toReference(session) as? FirNamedReferenceWithCandidate)?.candidate?.updateSourcesOfReceivers()
// 2. Handle candidate for `invoke`
candidate.updateSourcesOfReceivers()
functionCall.copyAsImplicitInvokeCall {
explicitReceiver = candidate.callInfo.explicitReceiver
dispatchReceiver = candidate.dispatchReceiverExpression()
@@ -126,7 +123,6 @@ class FirCallResolver(
contextReceiverArguments.addAll(candidate.contextReceiverArguments())
}
} else {
candidate?.updateSourcesOfReceivers()
functionCall
}
val type = components.typeFromCallee(resultFunctionCall).type
@@ -340,6 +340,9 @@ private fun BodyResolveComponents.createExplicitReceiverForInvokeByCallable(
if (candidate.currentApplicability == CandidateApplicability.K2_PROPERTY_AS_OPERATOR) {
nonFatalDiagnostics.add(ConePropertyAsOperator(candidate.symbol as FirPropertySymbol))
}
candidate.updateSourcesOfReceivers()
source = fakeSource
}.build().let {
callCompleter.completeCall(it, ResolutionMode.ReceiverResolution)
@@ -0,0 +1,28 @@
// ISSUE: KT-66148
class Controller<E>
fun <E1> generate(block: Controller<E1>.() -> Unit) {
block(Controller())
}
class A(val r: String)
fun foo(c: Controller<String>): A = A("OK")
fun bar(
propertyForInvoke: A.() -> Unit,
) {
generate {
foo(this).propertyForInvoke()
}
}
fun box(): String {
var result = "fail"
bar {
result = r
}
return result
}
@@ -0,0 +1,18 @@
// FIR_IDENTICAL
// ISSUE: KT-66148
interface Controller<E>
fun <E1> generate(block: Controller<E1>.() -> Unit) {}
class A
fun foo(c: Controller<String>): A = TODO()
fun bar(
propertyForInvoke: A.() -> Unit,
) {
generate {
foo(this).propertyForInvoke()
}
}
@@ -17807,6 +17807,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
runTest("compiler/testData/diagnostics/tests/inference/builderInference/overloadResolutionByLambdaReturnTypeInsideBI.kt");
}
@Test
@TestMetadata("propertyInvokeInsidePCLALambda.kt")
public void testPropertyInvokeInsidePCLALambda() {
runTest("compiler/testData/diagnostics/tests/inference/builderInference/propertyInvokeInsidePCLALambda.kt");
}
@Test
@TestMetadata("propertySubstitution.kt")
public void testPropertySubstitution() {
@@ -3537,6 +3537,12 @@ public class JvmAbiConsistencyTestBoxGenerated extends AbstractJvmAbiConsistency
runTest("compiler/testData/codegen/box/builderInference/posptonedPCLACallInsideStringInterpolation.kt");
}
@Test
@TestMetadata("propertyInvokeInsidePCLALambda.kt")
public void testPropertyInvokeInsidePCLALambda() {
runTest("compiler/testData/codegen/box/builderInference/propertyInvokeInsidePCLALambda.kt");
}
@Test
@TestMetadata("receiverUsesOuterTVButReturnTypeIsProper.kt")
public void testReceiverUsesOuterTVButReturnTypeIsProper() {
@@ -3345,6 +3345,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
runTest("compiler/testData/codegen/box/builderInference/posptonedPCLACallInsideStringInterpolation.kt");
}
@Test
@TestMetadata("propertyInvokeInsidePCLALambda.kt")
public void testPropertyInvokeInsidePCLALambda() {
runTest("compiler/testData/codegen/box/builderInference/propertyInvokeInsidePCLALambda.kt");
}
@Test
@TestMetadata("receiverUsesOuterTVButReturnTypeIsProper.kt")
public void testReceiverUsesOuterTVButReturnTypeIsProper() {
@@ -3537,6 +3537,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
runTest("compiler/testData/codegen/box/builderInference/posptonedPCLACallInsideStringInterpolation.kt");
}
@Test
@TestMetadata("propertyInvokeInsidePCLALambda.kt")
public void testPropertyInvokeInsidePCLALambda() {
runTest("compiler/testData/codegen/box/builderInference/propertyInvokeInsidePCLALambda.kt");
}
@Test
@TestMetadata("receiverUsesOuterTVButReturnTypeIsProper.kt")
public void testReceiverUsesOuterTVButReturnTypeIsProper() {
@@ -3537,6 +3537,12 @@ public class IrBlackBoxCodegenWithIrInlinerTestGenerated extends AbstractIrBlack
runTest("compiler/testData/codegen/box/builderInference/posptonedPCLACallInsideStringInterpolation.kt");
}
@Test
@TestMetadata("propertyInvokeInsidePCLALambda.kt")
public void testPropertyInvokeInsidePCLALambda() {
runTest("compiler/testData/codegen/box/builderInference/propertyInvokeInsidePCLALambda.kt");
}
@Test
@TestMetadata("receiverUsesOuterTVButReturnTypeIsProper.kt")
public void testReceiverUsesOuterTVButReturnTypeIsProper() {
@@ -3537,6 +3537,12 @@ public class FirBlackBoxCodegenTestWithInlineScopesGenerated extends AbstractFir
runTest("compiler/testData/codegen/box/builderInference/posptonedPCLACallInsideStringInterpolation.kt");
}
@Test
@TestMetadata("propertyInvokeInsidePCLALambda.kt")
public void testPropertyInvokeInsidePCLALambda() {
runTest("compiler/testData/codegen/box/builderInference/propertyInvokeInsidePCLALambda.kt");
}
@Test
@TestMetadata("receiverUsesOuterTVButReturnTypeIsProper.kt")
public void testReceiverUsesOuterTVButReturnTypeIsProper() {
@@ -3078,6 +3078,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
runTest("compiler/testData/codegen/box/builderInference/posptonedPCLACallInsideStringInterpolation.kt");
}
@TestMetadata("propertyInvokeInsidePCLALambda.kt")
public void testPropertyInvokeInsidePCLALambda() {
runTest("compiler/testData/codegen/box/builderInference/propertyInvokeInsidePCLALambda.kt");
}
@TestMetadata("receiverUsesOuterTVButReturnTypeIsProper.kt")
public void testReceiverUsesOuterTVButReturnTypeIsProper() {
runTest("compiler/testData/codegen/box/builderInference/receiverUsesOuterTVButReturnTypeIsProper.kt");
@@ -2631,6 +2631,12 @@ public class FirJsCodegenBoxTestGenerated extends AbstractFirJsCodegenBoxTest {
runTest("compiler/testData/codegen/box/builderInference/posptonedPCLACallInsideStringInterpolation.kt");
}
@Test
@TestMetadata("propertyInvokeInsidePCLALambda.kt")
public void testPropertyInvokeInsidePCLALambda() {
runTest("compiler/testData/codegen/box/builderInference/propertyInvokeInsidePCLALambda.kt");
}
@Test
@TestMetadata("receiverUsesOuterTVButReturnTypeIsProper.kt")
public void testReceiverUsesOuterTVButReturnTypeIsProper() {
@@ -2631,6 +2631,12 @@ public class FirJsES6CodegenBoxTestGenerated extends AbstractFirJsES6CodegenBoxT
runTest("compiler/testData/codegen/box/builderInference/posptonedPCLACallInsideStringInterpolation.kt");
}
@Test
@TestMetadata("propertyInvokeInsidePCLALambda.kt")
public void testPropertyInvokeInsidePCLALambda() {
runTest("compiler/testData/codegen/box/builderInference/propertyInvokeInsidePCLALambda.kt");
}
@Test
@TestMetadata("receiverUsesOuterTVButReturnTypeIsProper.kt")
public void testReceiverUsesOuterTVButReturnTypeIsProper() {
@@ -2631,6 +2631,12 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
runTest("compiler/testData/codegen/box/builderInference/posptonedPCLACallInsideStringInterpolation.kt");
}
@Test
@TestMetadata("propertyInvokeInsidePCLALambda.kt")
public void testPropertyInvokeInsidePCLALambda() {
runTest("compiler/testData/codegen/box/builderInference/propertyInvokeInsidePCLALambda.kt");
}
@Test
@TestMetadata("receiverUsesOuterTVButReturnTypeIsProper.kt")
public void testReceiverUsesOuterTVButReturnTypeIsProper() {
@@ -2631,6 +2631,12 @@ public class IrJsES6CodegenBoxTestGenerated extends AbstractIrJsES6CodegenBoxTes
runTest("compiler/testData/codegen/box/builderInference/posptonedPCLACallInsideStringInterpolation.kt");
}
@Test
@TestMetadata("propertyInvokeInsidePCLALambda.kt")
public void testPropertyInvokeInsidePCLALambda() {
runTest("compiler/testData/codegen/box/builderInference/propertyInvokeInsidePCLALambda.kt");
}
@Test
@TestMetadata("receiverUsesOuterTVButReturnTypeIsProper.kt")
public void testReceiverUsesOuterTVButReturnTypeIsProper() {
@@ -2705,6 +2705,12 @@ public class FirNativeCodegenBoxTestGenerated extends AbstractNativeCodegenBoxTe
runTest("compiler/testData/codegen/box/builderInference/posptonedPCLACallInsideStringInterpolation.kt");
}
@Test
@TestMetadata("propertyInvokeInsidePCLALambda.kt")
public void testPropertyInvokeInsidePCLALambda() {
runTest("compiler/testData/codegen/box/builderInference/propertyInvokeInsidePCLALambda.kt");
}
@Test
@TestMetadata("receiverUsesOuterTVButReturnTypeIsProper.kt")
public void testReceiverUsesOuterTVButReturnTypeIsProper() {
@@ -2761,6 +2761,12 @@ public class FirNativeCodegenBoxTestNoPLGenerated extends AbstractNativeCodegenB
runTest("compiler/testData/codegen/box/builderInference/posptonedPCLACallInsideStringInterpolation.kt");
}
@Test
@TestMetadata("propertyInvokeInsidePCLALambda.kt")
public void testPropertyInvokeInsidePCLALambda() {
runTest("compiler/testData/codegen/box/builderInference/propertyInvokeInsidePCLALambda.kt");
}
@Test
@TestMetadata("receiverUsesOuterTVButReturnTypeIsProper.kt")
public void testReceiverUsesOuterTVButReturnTypeIsProper() {
@@ -2649,6 +2649,12 @@ public class NativeCodegenBoxTestGenerated extends AbstractNativeCodegenBoxTest
runTest("compiler/testData/codegen/box/builderInference/posptonedPCLACallInsideStringInterpolation.kt");
}
@Test
@TestMetadata("propertyInvokeInsidePCLALambda.kt")
public void testPropertyInvokeInsidePCLALambda() {
runTest("compiler/testData/codegen/box/builderInference/propertyInvokeInsidePCLALambda.kt");
}
@Test
@TestMetadata("receiverUsesOuterTVButReturnTypeIsProper.kt")
public void testReceiverUsesOuterTVButReturnTypeIsProper() {
@@ -2706,6 +2706,12 @@ public class NativeCodegenBoxTestNoPLGenerated extends AbstractNativeCodegenBoxT
runTest("compiler/testData/codegen/box/builderInference/posptonedPCLACallInsideStringInterpolation.kt");
}
@Test
@TestMetadata("propertyInvokeInsidePCLALambda.kt")
public void testPropertyInvokeInsidePCLALambda() {
runTest("compiler/testData/codegen/box/builderInference/propertyInvokeInsidePCLALambda.kt");
}
@Test
@TestMetadata("receiverUsesOuterTVButReturnTypeIsProper.kt")
public void testReceiverUsesOuterTVButReturnTypeIsProper() {
@@ -2619,6 +2619,12 @@ public class FirWasmJsCodegenBoxTestGenerated extends AbstractFirWasmJsCodegenBo
runTest("compiler/testData/codegen/box/builderInference/posptonedPCLACallInsideStringInterpolation.kt");
}
@Test
@TestMetadata("propertyInvokeInsidePCLALambda.kt")
public void testPropertyInvokeInsidePCLALambda() {
runTest("compiler/testData/codegen/box/builderInference/propertyInvokeInsidePCLALambda.kt");
}
@Test
@TestMetadata("receiverUsesOuterTVButReturnTypeIsProper.kt")
public void testReceiverUsesOuterTVButReturnTypeIsProper() {
@@ -2619,6 +2619,12 @@ public class K1WasmCodegenBoxTestGenerated extends AbstractK1WasmCodegenBoxTest
runTest("compiler/testData/codegen/box/builderInference/posptonedPCLACallInsideStringInterpolation.kt");
}
@Test
@TestMetadata("propertyInvokeInsidePCLALambda.kt")
public void testPropertyInvokeInsidePCLALambda() {
runTest("compiler/testData/codegen/box/builderInference/propertyInvokeInsidePCLALambda.kt");
}
@Test
@TestMetadata("receiverUsesOuterTVButReturnTypeIsProper.kt")
public void testReceiverUsesOuterTVButReturnTypeIsProper() {