From 82611ad1242cc6808700c3b25f62f4e2eff76d1a Mon Sep 17 00:00:00 2001 From: Simon Ogorodnik Date: Tue, 2 May 2023 15:07:57 +0200 Subject: [PATCH] FIR. BI: Fix stub type leakage in builder inference Previously, updateTypeInBuilderInference was calling updateTypeFromSmartcast to actually perform type update in implicit receiver after stub types was inferred Such action results in creation of following FIR: FirSmartCastExpression( original=FQAE(FirImplicitThisReference, typeRef=R|Inv|) typeRef=R|Inv| ) in receiver position during completion of calls However, it wasn't the case in general situation due to action of FirStubTypeTransformer, which, in turn visits and updates type ref inside original expression, but only if there was at least one call (that was completed) using that implicit receiver As after such type update updateTypeFromSmartcast function does nothing Yet in situation, when there was only partially resolved calls referencing that implicit receiver we actually create smart-cast expression and don't update type The change just removes usage of updateTypeFromSmartcast and replaces is with direct type update We still mutate state of implicit receiver, potentially improperly, it should be addressed in future ^KT-54708 ^KT-58365 Fixed --- ...CompilerTestFE10TestdataTestGenerated.java | 6 ++++++ ...sticCompilerFE10TestDataTestGenerated.java | 6 ++++++ ...eeOldFrontendDiagnosticsTestGenerated.java | 6 ++++++ ...siOldFrontendDiagnosticsTestGenerated.java | 6 ++++++ .../kotlin/fir/resolve/calls/FirReceivers.kt | 6 ++++-- .../inference/FirBuilderInferenceSession.kt | 1 + .../box/inference/builderInference/kt51988.kt | 1 - .../builderInference/k2StubTypeLeak.kt | 20 +++++++++++++++++++ .../coroutines/inference/kt35684.fir.kt | 1 - .../coroutines/inference/kt35684.kt | 1 - .../test/runners/DiagnosticTestGenerated.java | 6 ++++++ 11 files changed, 55 insertions(+), 5 deletions(-) create mode 100644 compiler/testData/diagnostics/testsWithStdLib/builderInference/k2StubTypeLeak.kt diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosticCompilerTestFE10TestdataTestGenerated.java b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosticCompilerTestFE10TestdataTestGenerated.java index 1173b3759df..eef0b3aa019 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosticCompilerTestFE10TestdataTestGenerated.java +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosticCompilerTestFE10TestdataTestGenerated.java @@ -36820,6 +36820,12 @@ public class DiagnosticCompilerTestFE10TestdataTestGenerated extends AbstractDia runTest("compiler/testData/diagnostics/testsWithStdLib/builderInference/inferenceFromLambdaReturnType.kt"); } + @Test + @TestMetadata("k2StubTypeLeak.kt") + public void testK2StubTypeLeak() throws Exception { + runTest("compiler/testData/diagnostics/testsWithStdLib/builderInference/k2StubTypeLeak.kt"); + } + @Test @TestMetadata("resolveUsualCallWithBuilderInference.kt") public void testResolveUsualCallWithBuilderInference() throws Exception { diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated.java b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated.java index a1c90efee80..04a36c218f3 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated.java +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated.java @@ -36820,6 +36820,12 @@ public class LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated runTest("compiler/testData/diagnostics/testsWithStdLib/builderInference/inferenceFromLambdaReturnType.kt"); } + @Test + @TestMetadata("k2StubTypeLeak.kt") + public void testK2StubTypeLeak() throws Exception { + runTest("compiler/testData/diagnostics/testsWithStdLib/builderInference/k2StubTypeLeak.kt"); + } + @Test @TestMetadata("resolveUsualCallWithBuilderInference.kt") public void testResolveUsualCallWithBuilderInference() throws Exception { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLightTreeOldFrontendDiagnosticsTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLightTreeOldFrontendDiagnosticsTestGenerated.java index 89be1368d04..630da5e58f8 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLightTreeOldFrontendDiagnosticsTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLightTreeOldFrontendDiagnosticsTestGenerated.java @@ -36820,6 +36820,12 @@ public class FirLightTreeOldFrontendDiagnosticsTestGenerated extends AbstractFir runTest("compiler/testData/diagnostics/testsWithStdLib/builderInference/inferenceFromLambdaReturnType.kt"); } + @Test + @TestMetadata("k2StubTypeLeak.kt") + public void testK2StubTypeLeak() throws Exception { + runTest("compiler/testData/diagnostics/testsWithStdLib/builderInference/k2StubTypeLeak.kt"); + } + @Test @TestMetadata("resolveUsualCallWithBuilderInference.kt") public void testResolveUsualCallWithBuilderInference() throws Exception { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiOldFrontendDiagnosticsTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiOldFrontendDiagnosticsTestGenerated.java index 8424dbfcdfa..9dd028cad70 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiOldFrontendDiagnosticsTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiOldFrontendDiagnosticsTestGenerated.java @@ -36916,6 +36916,12 @@ public class FirPsiOldFrontendDiagnosticsTestGenerated extends AbstractFirPsiDia runTest("compiler/testData/diagnostics/testsWithStdLib/builderInference/inferenceFromLambdaReturnType.kt"); } + @Test + @TestMetadata("k2StubTypeLeak.kt") + public void testK2StubTypeLeak() throws Exception { + runTest("compiler/testData/diagnostics/testsWithStdLib/builderInference/k2StubTypeLeak.kt"); + } + @Test @TestMetadata("resolveUsualCallWithBuilderInference.kt") public void testResolveUsualCallWithBuilderInference() throws Exception { diff --git a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/resolve/calls/FirReceivers.kt b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/resolve/calls/FirReceivers.kt index e471e0099c9..b8a11d8f8f9 100644 --- a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/resolve/calls/FirReceivers.kt +++ b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/resolve/calls/FirReceivers.kt @@ -105,10 +105,12 @@ sealed class ImplicitReceiverValue>( @RequiresOptIn annotation class ImplicitReceiverInternals - @OptIn(ImplicitReceiverInternals::class) @Deprecated(level = DeprecationLevel.ERROR, message = "Builder inference should not modify implicit receivers. KT-54708") fun updateTypeInBuilderInference(type: ConeKotlinType) { - updateTypeFromSmartcast(type) + this.type = type + receiverExpression = receiverExpression(boundSymbol, type, contextReceiverNumber) + implicitScope = + type.scope(useSiteSession, scopeSession, FakeOverrideTypeCalculator.DoNothing, requiredPhase = FirResolvePhase.STATUS) } /* diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirBuilderInferenceSession.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirBuilderInferenceSession.kt index 13fb95a2cb5..fb9b8cdfc1d 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirBuilderInferenceSession.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/inference/FirBuilderInferenceSession.kt @@ -241,6 +241,7 @@ class FirBuilderInferenceSession( val stubTypeSubstitutor = FirStubTypeTransformer(substitutor) lambda.transformSingle(stubTypeSubstitutor, null) + // TODO: Builder inference should not modify implicit receivers. KT-54708 for (receiver in lambdaImplicitReceivers) { @Suppress("DEPRECATION_ERROR") receiver.updateTypeInBuilderInference(substitutor.substituteOrSelf(receiver.type)) diff --git a/compiler/testData/codegen/box/inference/builderInference/kt51988.kt b/compiler/testData/codegen/box/inference/builderInference/kt51988.kt index d47e24cd968..cf3af2230b9 100644 --- a/compiler/testData/codegen/box/inference/builderInference/kt51988.kt +++ b/compiler/testData/codegen/box/inference/builderInference/kt51988.kt @@ -1,4 +1,3 @@ -// IGNORE_LEAKED_INTERNAL_TYPES: KT-54708 // WITH_STDLIB import kotlin.experimental.ExperimentalTypeInference diff --git a/compiler/testData/diagnostics/testsWithStdLib/builderInference/k2StubTypeLeak.kt b/compiler/testData/diagnostics/testsWithStdLib/builderInference/k2StubTypeLeak.kt new file mode 100644 index 00000000000..401955bd070 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/builderInference/k2StubTypeLeak.kt @@ -0,0 +1,20 @@ +// FIR_IDENTICAL +// !DIAGNOSTICS: -UNUSED_PARAMETER +fun test_1() { + sequence { + constrain(this) + yieldAll(mk()) // Will be completed in partial mode, due to builder inference + + Unit + } +} + +fun constrain(t: Inv) {} + +fun sequence(block: Inv.() -> Unit): U = null!! + +interface Inv { + fun yieldAll(seq: Inv) +} + +fun mk(): K = TODO() diff --git a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/kt35684.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/kt35684.fir.kt index 49460a455d1..2ec35f51572 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/kt35684.fir.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/kt35684.fir.kt @@ -1,4 +1,3 @@ -// IGNORE_LEAKED_INTERNAL_TYPES: KT-54708 // !OPT_IN: kotlin.RequiresOptIn // !DIAGNOSTICS: -UNUSED_PARAMETER // ISSUE: KT-35684 diff --git a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/kt35684.kt b/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/kt35684.kt index 1af4850a359..cde719d0e78 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/kt35684.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/kt35684.kt @@ -1,4 +1,3 @@ -// IGNORE_LEAKED_INTERNAL_TYPES: KT-54708 // !OPT_IN: kotlin.RequiresOptIn // !DIAGNOSTICS: -UNUSED_PARAMETER // ISSUE: KT-35684 diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java index 819bd96ddc5..f07c1b7b892 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java @@ -37688,6 +37688,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest { runTest("compiler/testData/diagnostics/testsWithStdLib/builderInference/inferenceFromLambdaReturnType.kt"); } + @Test + @TestMetadata("k2StubTypeLeak.kt") + public void testK2StubTypeLeak() throws Exception { + runTest("compiler/testData/diagnostics/testsWithStdLib/builderInference/k2StubTypeLeak.kt"); + } + @Test @TestMetadata("resolveUsualCallWithBuilderInference.kt") public void testResolveUsualCallWithBuilderInference() throws Exception {