[FIR] Fix raw type nullability computation
Consider the nullability of the type arguments, not of the type. This fixes a false positive ARGUMENT_TYPE_MISMATCH. #KT-66294 Fixed
This commit is contained in:
committed by
Space Team
parent
df878918ee
commit
172df04c9b
+6
@@ -22432,6 +22432,12 @@ public class DiagnosticCompilerTestFE10TestdataTestGenerated extends AbstractDia
|
||||
runTest("compiler/testData/diagnostics/tests/j+k/nullForOptionalOrElse.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("nullableRawTypeWithFlexibleArguments.kt")
|
||||
public void testNullableRawTypeWithFlexibleArguments() {
|
||||
runTest("compiler/testData/diagnostics/tests/j+k/nullableRawTypeWithFlexibleArguments.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("orderOfSupertypesAndFakeOverrides_1.kt")
|
||||
public void testOrderOfSupertypesAndFakeOverrides_1() {
|
||||
|
||||
+6
@@ -22432,6 +22432,12 @@ public class LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated
|
||||
runTest("compiler/testData/diagnostics/tests/j+k/nullForOptionalOrElse.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("nullableRawTypeWithFlexibleArguments.kt")
|
||||
public void testNullableRawTypeWithFlexibleArguments() {
|
||||
runTest("compiler/testData/diagnostics/tests/j+k/nullableRawTypeWithFlexibleArguments.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("orderOfSupertypesAndFakeOverrides_1.kt")
|
||||
public void testOrderOfSupertypesAndFakeOverrides_1() {
|
||||
|
||||
+6
@@ -22426,6 +22426,12 @@ public class FirLightTreeOldFrontendDiagnosticsTestGenerated extends AbstractFir
|
||||
runTest("compiler/testData/diagnostics/tests/j+k/nullForOptionalOrElse.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("nullableRawTypeWithFlexibleArguments.kt")
|
||||
public void testNullableRawTypeWithFlexibleArguments() {
|
||||
runTest("compiler/testData/diagnostics/tests/j+k/nullableRawTypeWithFlexibleArguments.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("orderOfSupertypesAndFakeOverrides_1.kt")
|
||||
public void testOrderOfSupertypesAndFakeOverrides_1() {
|
||||
|
||||
+6
@@ -22432,6 +22432,12 @@ public class FirPsiOldFrontendDiagnosticsTestGenerated extends AbstractFirPsiDia
|
||||
runTest("compiler/testData/diagnostics/tests/j+k/nullForOptionalOrElse.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("nullableRawTypeWithFlexibleArguments.kt")
|
||||
public void testNullableRawTypeWithFlexibleArguments() {
|
||||
runTest("compiler/testData/diagnostics/tests/j+k/nullableRawTypeWithFlexibleArguments.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("orderOfSupertypesAndFakeOverrides_1.kt")
|
||||
public void testOrderOfSupertypesAndFakeOverrides_1() {
|
||||
|
||||
@@ -200,7 +200,7 @@ private fun JavaClassifierType.toConeKotlinTypeForFlexibleBound(
|
||||
// Given `C<T : X>`, `C` -> `C<X>..C<*>?`.
|
||||
when {
|
||||
mode.insideAnnotation -> Array(classifier.allTypeParametersNumber()) { ConeStarProjection }
|
||||
else -> typeParameterSymbols?.getProjectionsForRawType(session, makeNullable = false)
|
||||
else -> typeParameterSymbols?.getProjectionsForRawType(session, nullabilities = null)
|
||||
?: Array(classifier.allTypeParametersNumber()) { ConeStarProjection }
|
||||
}
|
||||
}
|
||||
|
||||
+5
-2
@@ -281,7 +281,7 @@ class ConeRawScopeSubstitutor(
|
||||
return when {
|
||||
type is ConeTypeParameterType -> {
|
||||
substituteOrSelf(
|
||||
listOf(type.lookupTag.symbol).getProjectionsForRawType(useSiteSession, makeNullable = type.isNullable)[0]
|
||||
type.lookupTag.symbol.getProjectionForRawType(useSiteSession, makeNullable = type.isMarkedNullable)
|
||||
)
|
||||
}
|
||||
type is ConeClassLikeType && type.typeArguments.isNotEmpty() -> {
|
||||
@@ -295,8 +295,11 @@ class ConeRawScopeSubstitutor(
|
||||
}
|
||||
|
||||
val firClass = type.fullyExpandedType(useSiteSession).lookupTag.toFirRegularClassSymbol(useSiteSession) ?: return null
|
||||
val nullabilities = BooleanArray(type.typeArguments.size) { type.typeArguments[it].type?.isMarkedNullable == true }
|
||||
ConeRawType.create(
|
||||
type.withArguments(firClass.typeParameterSymbols.getProjectionsForRawType(useSiteSession, makeNullable = type.isNullable)),
|
||||
type.withArguments(
|
||||
firClass.typeParameterSymbols.getProjectionsForRawType(useSiteSession, nullabilities = nullabilities)
|
||||
),
|
||||
type.replaceArgumentsWithStarProjections()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -689,15 +689,32 @@ fun List<FirTypeParameterSymbol>.eraseToUpperBoundsAssociated(
|
||||
}
|
||||
}
|
||||
|
||||
fun List<FirTypeParameterSymbol>.getProjectionsForRawType(session: FirSession, makeNullable: Boolean): Array<ConeKotlinType> {
|
||||
fun List<FirTypeParameterSymbol>.getProjectionsForRawType(session: FirSession, nullabilities: BooleanArray?): Array<ConeKotlinType> {
|
||||
val cache = mutableMapOf<FirTypeParameter, ConeKotlinType>()
|
||||
return Array(size) { index ->
|
||||
this[index].fir.eraseToUpperBound(
|
||||
session, cache, mode = EraseUpperBoundMode.FOR_RAW_TYPE_ERASURE
|
||||
).applyIf(makeNullable) { withNullability(ConeNullability.NULLABLE, session.typeContext) }
|
||||
this[index].getProjectionForRawType(session, cache, nullabilities?.get(index) == true)
|
||||
}
|
||||
}
|
||||
|
||||
fun FirTypeParameterSymbol.getProjectionForRawType(
|
||||
session: FirSession,
|
||||
makeNullable: Boolean,
|
||||
): ConeKotlinType {
|
||||
return getProjectionForRawType(session, mutableMapOf(), makeNullable)
|
||||
}
|
||||
|
||||
private fun FirTypeParameterSymbol.getProjectionForRawType(
|
||||
session: FirSession,
|
||||
cache: MutableMap<FirTypeParameter, ConeKotlinType>,
|
||||
makeNullable: Boolean,
|
||||
): ConeKotlinType {
|
||||
return fir.eraseToUpperBound(session, cache, mode = EraseUpperBoundMode.FOR_RAW_TYPE_ERASURE)
|
||||
.applyIf(makeNullable) {
|
||||
withNullability(ConeNullability.NULLABLE, session.typeContext)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private enum class EraseUpperBoundMode {
|
||||
FOR_RAW_TYPE_ERASURE,
|
||||
FOR_EMPTY_INTERSECTION_CHECK
|
||||
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
// FIR_IDENTICAL
|
||||
// FILE: J.java
|
||||
package test;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
class Editor<BC extends BuildConfiguration, TARGET extends BuildTarget<BC>> {
|
||||
public void onTargetSelected(@Nullable TARGET target) {}
|
||||
}
|
||||
|
||||
interface BuildConfiguration {}
|
||||
interface BuildTarget<BC extends BuildConfiguration> {}
|
||||
|
||||
class Helper extends AbstractHelper {}
|
||||
|
||||
abstract class AbstractHelper<BC extends BuildConfiguration, TARGET extends BuildTarget<BC>> {
|
||||
@Nullable
|
||||
public TARGET findRunTarget() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// FILE: test.kt
|
||||
package test
|
||||
|
||||
private fun test(
|
||||
editor: Editor<BuildConfiguration, BuildTarget<BuildConfiguration>>,
|
||||
helper: Helper,
|
||||
) {
|
||||
editor.onTargetSelected(helper.findRunTarget())
|
||||
}
|
||||
Generated
+6
@@ -22432,6 +22432,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
|
||||
runTest("compiler/testData/diagnostics/tests/j+k/nullForOptionalOrElse.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("nullableRawTypeWithFlexibleArguments.kt")
|
||||
public void testNullableRawTypeWithFlexibleArguments() {
|
||||
runTest("compiler/testData/diagnostics/tests/j+k/nullableRawTypeWithFlexibleArguments.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("orderOfSupertypesAndFakeOverrides_1.kt")
|
||||
public void testOrderOfSupertypesAndFakeOverrides_1() {
|
||||
|
||||
Reference in New Issue
Block a user