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<Stub>|)
    typeRef=R|Inv<String>|
)

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
This commit is contained in:
Simon Ogorodnik
2023-05-02 15:07:57 +02:00
committed by Space Team
parent af7d6b1bb3
commit 82611ad124
11 changed files with 55 additions and 5 deletions
@@ -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 {
@@ -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 {
@@ -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 {
@@ -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 {
@@ -105,10 +105,12 @@ sealed class ImplicitReceiverValue<S : FirBasedSymbol<*>>(
@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)
}
/*
@@ -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))
@@ -1,4 +1,3 @@
// IGNORE_LEAKED_INTERNAL_TYPES: KT-54708
// WITH_STDLIB
import kotlin.experimental.ExperimentalTypeInference
@@ -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<String>) {}
fun <U> sequence(block: Inv<U>.() -> Unit): U = null!!
interface Inv<T> {
fun <S: T> yieldAll(seq: Inv<S>)
}
fun <K> mk(): K = TODO()
@@ -1,4 +1,3 @@
// IGNORE_LEAKED_INTERNAL_TYPES: KT-54708
// !OPT_IN: kotlin.RequiresOptIn
// !DIAGNOSTICS: -UNUSED_PARAMETER
// ISSUE: KT-35684
@@ -1,4 +1,3 @@
// IGNORE_LEAKED_INTERNAL_TYPES: KT-54708
// !OPT_IN: kotlin.RequiresOptIn
// !DIAGNOSTICS: -UNUSED_PARAMETER
// ISSUE: KT-35684
@@ -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 {