[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");
|
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
|
@Test
|
||||||
@TestMetadata("orderOfSupertypesAndFakeOverrides_1.kt")
|
@TestMetadata("orderOfSupertypesAndFakeOverrides_1.kt")
|
||||||
public void testOrderOfSupertypesAndFakeOverrides_1() {
|
public void testOrderOfSupertypesAndFakeOverrides_1() {
|
||||||
|
|||||||
+6
@@ -22432,6 +22432,12 @@ public class LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated
|
|||||||
runTest("compiler/testData/diagnostics/tests/j+k/nullForOptionalOrElse.kt");
|
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
|
@Test
|
||||||
@TestMetadata("orderOfSupertypesAndFakeOverrides_1.kt")
|
@TestMetadata("orderOfSupertypesAndFakeOverrides_1.kt")
|
||||||
public void testOrderOfSupertypesAndFakeOverrides_1() {
|
public void testOrderOfSupertypesAndFakeOverrides_1() {
|
||||||
|
|||||||
+6
@@ -22426,6 +22426,12 @@ public class FirLightTreeOldFrontendDiagnosticsTestGenerated extends AbstractFir
|
|||||||
runTest("compiler/testData/diagnostics/tests/j+k/nullForOptionalOrElse.kt");
|
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
|
@Test
|
||||||
@TestMetadata("orderOfSupertypesAndFakeOverrides_1.kt")
|
@TestMetadata("orderOfSupertypesAndFakeOverrides_1.kt")
|
||||||
public void testOrderOfSupertypesAndFakeOverrides_1() {
|
public void testOrderOfSupertypesAndFakeOverrides_1() {
|
||||||
|
|||||||
+6
@@ -22432,6 +22432,12 @@ public class FirPsiOldFrontendDiagnosticsTestGenerated extends AbstractFirPsiDia
|
|||||||
runTest("compiler/testData/diagnostics/tests/j+k/nullForOptionalOrElse.kt");
|
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
|
@Test
|
||||||
@TestMetadata("orderOfSupertypesAndFakeOverrides_1.kt")
|
@TestMetadata("orderOfSupertypesAndFakeOverrides_1.kt")
|
||||||
public void testOrderOfSupertypesAndFakeOverrides_1() {
|
public void testOrderOfSupertypesAndFakeOverrides_1() {
|
||||||
|
|||||||
@@ -200,7 +200,7 @@ private fun JavaClassifierType.toConeKotlinTypeForFlexibleBound(
|
|||||||
// Given `C<T : X>`, `C` -> `C<X>..C<*>?`.
|
// Given `C<T : X>`, `C` -> `C<X>..C<*>?`.
|
||||||
when {
|
when {
|
||||||
mode.insideAnnotation -> Array(classifier.allTypeParametersNumber()) { ConeStarProjection }
|
mode.insideAnnotation -> Array(classifier.allTypeParametersNumber()) { ConeStarProjection }
|
||||||
else -> typeParameterSymbols?.getProjectionsForRawType(session, makeNullable = false)
|
else -> typeParameterSymbols?.getProjectionsForRawType(session, nullabilities = null)
|
||||||
?: Array(classifier.allTypeParametersNumber()) { ConeStarProjection }
|
?: Array(classifier.allTypeParametersNumber()) { ConeStarProjection }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-2
@@ -281,7 +281,7 @@ class ConeRawScopeSubstitutor(
|
|||||||
return when {
|
return when {
|
||||||
type is ConeTypeParameterType -> {
|
type is ConeTypeParameterType -> {
|
||||||
substituteOrSelf(
|
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() -> {
|
type is ConeClassLikeType && type.typeArguments.isNotEmpty() -> {
|
||||||
@@ -295,8 +295,11 @@ class ConeRawScopeSubstitutor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
val firClass = type.fullyExpandedType(useSiteSession).lookupTag.toFirRegularClassSymbol(useSiteSession) ?: return null
|
val firClass = type.fullyExpandedType(useSiteSession).lookupTag.toFirRegularClassSymbol(useSiteSession) ?: return null
|
||||||
|
val nullabilities = BooleanArray(type.typeArguments.size) { type.typeArguments[it].type?.isMarkedNullable == true }
|
||||||
ConeRawType.create(
|
ConeRawType.create(
|
||||||
type.withArguments(firClass.typeParameterSymbols.getProjectionsForRawType(useSiteSession, makeNullable = type.isNullable)),
|
type.withArguments(
|
||||||
|
firClass.typeParameterSymbols.getProjectionsForRawType(useSiteSession, nullabilities = nullabilities)
|
||||||
|
),
|
||||||
type.replaceArgumentsWithStarProjections()
|
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>()
|
val cache = mutableMapOf<FirTypeParameter, ConeKotlinType>()
|
||||||
return Array(size) { index ->
|
return Array(size) { index ->
|
||||||
this[index].fir.eraseToUpperBound(
|
this[index].getProjectionForRawType(session, cache, nullabilities?.get(index) == true)
|
||||||
session, cache, mode = EraseUpperBoundMode.FOR_RAW_TYPE_ERASURE
|
|
||||||
).applyIf(makeNullable) { withNullability(ConeNullability.NULLABLE, session.typeContext) }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 {
|
private enum class EraseUpperBoundMode {
|
||||||
FOR_RAW_TYPE_ERASURE,
|
FOR_RAW_TYPE_ERASURE,
|
||||||
FOR_EMPTY_INTERSECTION_CHECK
|
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");
|
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
|
@Test
|
||||||
@TestMetadata("orderOfSupertypesAndFakeOverrides_1.kt")
|
@TestMetadata("orderOfSupertypesAndFakeOverrides_1.kt")
|
||||||
public void testOrderOfSupertypesAndFakeOverrides_1() {
|
public void testOrderOfSupertypesAndFakeOverrides_1() {
|
||||||
|
|||||||
Reference in New Issue
Block a user