FIR: Preserve K1 behavior for synthetic properties on raw type
^KT-54502 Fixed
This commit is contained in:
committed by
Space Team
parent
7b15b28ee2
commit
c0e0900344
+6
@@ -24223,6 +24223,12 @@ public class DiagnosisCompilerTestFE10TestdataTestGenerated extends AbstractDiag
|
||||
runTest("compiler/testData/diagnostics/tests/platformTypes/rawTypes/rawTypeInUpperBound.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("rawTypeSyntheticExtensions.kt")
|
||||
public void testRawTypeSyntheticExtensions() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/platformTypes/rawTypes/rawTypeSyntheticExtensions.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("rawWithInProjection.kt")
|
||||
public void testRawWithInProjection() throws Exception {
|
||||
|
||||
+6
@@ -24223,6 +24223,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
|
||||
runTest("compiler/testData/diagnostics/tests/platformTypes/rawTypes/rawTypeInUpperBound.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("rawTypeSyntheticExtensions.kt")
|
||||
public void testRawTypeSyntheticExtensions() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/platformTypes/rawTypes/rawTypeSyntheticExtensions.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("rawWithInProjection.kt")
|
||||
public void testRawWithInProjection() throws Exception {
|
||||
|
||||
+6
@@ -24223,6 +24223,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac
|
||||
runTest("compiler/testData/diagnostics/tests/platformTypes/rawTypes/rawTypeInUpperBound.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("rawTypeSyntheticExtensions.kt")
|
||||
public void testRawTypeSyntheticExtensions() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/platformTypes/rawTypes/rawTypeSyntheticExtensions.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("rawWithInProjection.kt")
|
||||
public void testRawWithInProjection() throws Exception {
|
||||
|
||||
@@ -29,6 +29,7 @@ import org.jetbrains.kotlin.fir.types.builder.buildErrorTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
|
||||
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
|
||||
import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl
|
||||
import org.jetbrains.kotlin.fir.types.lowerBoundIfFlexible
|
||||
import org.jetbrains.kotlin.resolve.calls.NewCommonSuperTypeCalculator
|
||||
import org.jetbrains.kotlin.types.*
|
||||
import org.jetbrains.kotlin.types.model.*
|
||||
@@ -850,3 +851,18 @@ private fun ConeKotlinType.eraseAsUpperBound(
|
||||
|
||||
else -> error("unexpected Java type parameter upper bound kind: $this")
|
||||
}
|
||||
|
||||
fun ConeKotlinType.isRaw(): Boolean = lowerBoundIfFlexible().attributes.contains(CompilerConeAttributes.RawType)
|
||||
|
||||
fun ConeKotlinType.convertToNonRawVersion(): ConeKotlinType {
|
||||
if (!isRaw()) return this
|
||||
|
||||
if (this is ConeFlexibleType) {
|
||||
return ConeFlexibleType(
|
||||
lowerBound.withAttributes(this.attributes.remove(CompilerConeAttributes.RawType)),
|
||||
upperBound,
|
||||
)
|
||||
}
|
||||
|
||||
return withAttributes(attributes.remove(CompilerConeAttributes.RawType))
|
||||
}
|
||||
|
||||
+24
-2
@@ -105,10 +105,31 @@ class MemberScopeTowerLevel(
|
||||
}
|
||||
|
||||
if (givenExtensionReceiverOptions.isEmpty()) {
|
||||
val dispatchReceiverType = dispatchReceiverValue.type
|
||||
|
||||
val useSiteForSyntheticScope: FirTypeScope
|
||||
val typeForSyntheticScope: ConeKotlinType
|
||||
|
||||
// In K1, synthetic properties were working a bit differently
|
||||
// - On first step they've been built on the per-class level
|
||||
// - Then, they've been handled as regular extensions with specific receiver value
|
||||
// In K2, we build those properties using specific use-site scope of given receiver
|
||||
// And that gives us different results in case of raw types (since we've got special scopes for them)
|
||||
// So, here we decide to preserve the K1 behavior just by converting the type to its non-raw version
|
||||
if (dispatchReceiverType.isRaw()) {
|
||||
typeForSyntheticScope = dispatchReceiverType.convertToNonRawVersion()
|
||||
useSiteForSyntheticScope =
|
||||
typeForSyntheticScope.scope(session, scopeSession, FakeOverrideTypeCalculator.DoNothing)
|
||||
?: error("No scope for flexible type scope, while it's not null for $dispatchReceiverType")
|
||||
} else {
|
||||
typeForSyntheticScope = dispatchReceiverType
|
||||
useSiteForSyntheticScope = scope
|
||||
}
|
||||
|
||||
val withSynthetic = FirSyntheticPropertiesScope.createIfSyntheticNamesProviderIsDefined(
|
||||
session,
|
||||
dispatchReceiverValue.type,
|
||||
scope
|
||||
typeForSyntheticScope,
|
||||
useSiteForSyntheticScope,
|
||||
)
|
||||
withSynthetic?.processScopeMembers { symbol ->
|
||||
empty = false
|
||||
@@ -320,6 +341,7 @@ class ScopeTowerLevel(
|
||||
(implicitReceiverValue.type as? ConeClassLikeType)?.fullyExpandedType(session)?.lookupTag == lookupTag
|
||||
}
|
||||
}
|
||||
|
||||
else -> {
|
||||
bodyResolveComponents.implicitReceiverStack.lastDispatchReceiver()
|
||||
}
|
||||
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
// SKIP_TXT
|
||||
// FIR_IDENTICAL
|
||||
// FILE: Generic.java
|
||||
import java.util.List;
|
||||
|
||||
public class Generic<T extends Generic> {
|
||||
// Returns Raw type
|
||||
public static Generic create() { return null; }
|
||||
public List<String> getFoo() { return null; }
|
||||
|
||||
public T getChild() { return null; }
|
||||
public List<Generic> getChildren() { return null; }
|
||||
}
|
||||
|
||||
// FILE: main.kt
|
||||
fun main() {
|
||||
val generic = Generic.create() // has a type of Generic<(raw) Any..Any?>
|
||||
|
||||
generic.getFoo() // has return type List<(raw) Any..Any?>
|
||||
generic.getFoo()[0].<!UNRESOLVED_REFERENCE!>length<!> // Unresolved "length"
|
||||
generic.foo[0].length // OK
|
||||
|
||||
generic.child.children[0].foo[0].length // OK
|
||||
}
|
||||
Generated
+6
@@ -24229,6 +24229,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
|
||||
runTest("compiler/testData/diagnostics/tests/platformTypes/rawTypes/rawTypeInUpperBound.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("rawTypeSyntheticExtensions.kt")
|
||||
public void testRawTypeSyntheticExtensions() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/platformTypes/rawTypes/rawTypeSyntheticExtensions.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("rawWithInProjection.kt")
|
||||
public void testRawWithInProjection() throws Exception {
|
||||
|
||||
Reference in New Issue
Block a user