K2: Fix generic inference case with !! synthetic call
Result of the `checkNotNull` calls should always be a non-nullable values. The simplest idea how to acheive it is adding not-nullable Any bound to the type parameter declaration. Existing comment stating about impossibility of such bound seems to be not 100% correct because it doesn't take into account presence of definitely-non-nullable X & Any types that allow described case with nullable generic. ^KT-55804 Fixed
This commit is contained in:
committed by
Space Team
parent
352316ba9f
commit
56557fb8ff
+6
@@ -14366,6 +14366,12 @@ public class FirLightTreeOldFrontendDiagnosticsTestGenerated extends AbstractFir
|
||||
runTest("compiler/testData/diagnostics/tests/inference/errorsOnImplicitInvokeInSimpleCall.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("exclExclInference.kt")
|
||||
public void testExclExclInference() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/inference/exclExclInference.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("expectedTypeAdditionalTest.kt")
|
||||
public void testExpectedTypeAdditionalTest() throws Exception {
|
||||
|
||||
+6
@@ -14372,6 +14372,12 @@ public class FirPsiOldFrontendDiagnosticsTestGenerated extends AbstractFirPsiDia
|
||||
runTest("compiler/testData/diagnostics/tests/inference/errorsOnImplicitInvokeInSimpleCall.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("exclExclInference.kt")
|
||||
public void testExclExclInference() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/inference/exclExclInference.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("expectedTypeAdditionalTest.kt")
|
||||
public void testExpectedTypeAdditionalTest() throws Exception {
|
||||
|
||||
+12
-8
@@ -239,7 +239,10 @@ class FirSyntheticCallGenerator(
|
||||
containingDeclarations = components.containingDeclarations
|
||||
)
|
||||
|
||||
private fun generateSyntheticSelectTypeParameter(functionSymbol: FirSyntheticFunctionSymbol): Pair<FirTypeParameter, FirResolvedTypeRef> {
|
||||
private fun generateSyntheticSelectTypeParameter(
|
||||
functionSymbol: FirSyntheticFunctionSymbol,
|
||||
isNullableBound: Boolean = true,
|
||||
): Pair<FirTypeParameter, FirResolvedTypeRef> {
|
||||
val typeParameterSymbol = FirTypeParameterSymbol()
|
||||
val typeParameter =
|
||||
buildTypeParameter {
|
||||
@@ -251,7 +254,12 @@ class FirSyntheticCallGenerator(
|
||||
containingDeclarationSymbol = functionSymbol
|
||||
variance = Variance.INVARIANT
|
||||
isReified = false
|
||||
addDefaultBoundIfNecessary()
|
||||
|
||||
if (!isNullableBound) {
|
||||
bounds += moduleData.session.builtinTypes.anyType
|
||||
} else {
|
||||
addDefaultBoundIfNecessary()
|
||||
}
|
||||
}
|
||||
|
||||
val typeParameterTypeRef = buildResolvedTypeRef { type = ConeTypeParameterTypeImpl(typeParameterSymbol.toLookupTag(), false) }
|
||||
@@ -280,13 +288,9 @@ class FirSyntheticCallGenerator(
|
||||
|
||||
private fun generateSyntheticCheckNotNullFunction(): FirSimpleFunction {
|
||||
// Synthetic function signature:
|
||||
// fun <K> checkNotNull(arg: K?): K
|
||||
//
|
||||
// Note: The upper bound of `K` cannot be `Any` because of the following case:
|
||||
// fun <X> test(a: X) = a!!
|
||||
// `X` is not a subtype of `Any` and hence cannot satisfy `K` if it had an upper bound of `Any`.
|
||||
// fun <K : Any> checkNotNull(arg: K?): K
|
||||
val functionSymbol = FirSyntheticFunctionSymbol(SyntheticCallableId.CHECK_NOT_NULL)
|
||||
val (typeParameter, returnType) = generateSyntheticSelectTypeParameter(functionSymbol)
|
||||
val (typeParameter, returnType) = generateSyntheticSelectTypeParameter(functionSymbol, isNullableBound = false)
|
||||
|
||||
val argumentType = buildResolvedTypeRef {
|
||||
type = returnType.type.withNullability(ConeNullability.NULLABLE, session.typeContext)
|
||||
|
||||
Reference in New Issue
Block a user