diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java index 0798197d65f..8ac16c5742f 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerTestFE10TestdataTestGenerated.java @@ -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 { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java index a0e834c30d7..b02e2fbbd9b 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsTestGenerated.java @@ -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 { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java index daf6c438c8a..c4376c68088 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirOldFrontendDiagnosticsWithLightTreeTestGenerated.java @@ -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 { diff --git a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/types/TypeUtils.kt b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/types/TypeUtils.kt index 24ce5e52c0b..c3bb842df95 100644 --- a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/types/TypeUtils.kt +++ b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/types/TypeUtils.kt @@ -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)) +} diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/TowerLevels.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/TowerLevels.kt index a1dafcf554e..f7d34402efe 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/TowerLevels.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/TowerLevels.kt @@ -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() } diff --git a/compiler/testData/diagnostics/tests/platformTypes/rawTypes/rawTypeSyntheticExtensions.kt b/compiler/testData/diagnostics/tests/platformTypes/rawTypes/rawTypeSyntheticExtensions.kt new file mode 100644 index 00000000000..b1c683a23b8 --- /dev/null +++ b/compiler/testData/diagnostics/tests/platformTypes/rawTypes/rawTypeSyntheticExtensions.kt @@ -0,0 +1,24 @@ +// SKIP_TXT +// FIR_IDENTICAL +// FILE: Generic.java +import java.util.List; + +public class Generic { + // Returns Raw type + public static Generic create() { return null; } + public List getFoo() { return null; } + + public T getChild() { return null; } + public List 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].length // Unresolved "length" + generic.foo[0].length // OK + + generic.child.children[0].foo[0].length // OK +} 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 5b178827170..d7acdf3d690 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 @@ -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 {