mirror of
https://github.com/jlengrand/kotlin.git
synced 2026-03-10 08:31:29 +00:00
FE: do not enhance ? in jspecify NullMarked scope
No clue whether this should be done for `@TypeQualifierDefault` since it appears to have no specification whatsoever. #KT-48262 Fixed
This commit is contained in:
@@ -1,35 +0,0 @@
|
||||
// JSPECIFY_STATE: strict
|
||||
// MUTE_FOR_PSI_CLASS_FILES_READING
|
||||
|
||||
// FILE: WildcardsWithDefault.java
|
||||
import org.jspecify.nullness.*;
|
||||
|
||||
@NullMarked
|
||||
public class WildcardsWithDefault {
|
||||
public void noBoundsNotNull(A<?, ?, ?> a) {}
|
||||
public void noBoundsNullable(A<? extends @Nullable Object, ? extends @Nullable Object, ? extends @Nullable Object> a) {}
|
||||
}
|
||||
|
||||
// FILE: A.java
|
||||
import org.jspecify.nullness.*;
|
||||
|
||||
public class A <T extends Object, E extends @Nullable Object, F extends @NullnessUnspecified Object> {}
|
||||
|
||||
// FILE: main.kt
|
||||
fun main(
|
||||
aNotNullNotNullNotNull: A<Any, Any, Any>,
|
||||
aNotNullNotNullNull: A<Any, Any, Any?>,
|
||||
aNotNullNullNotNull: A<Any, Any?, Any>,
|
||||
aNotNullNullNull: A<Any, Any?, Any?>,
|
||||
b: WildcardsWithDefault
|
||||
): Unit {
|
||||
b.noBoundsNotNull(aNotNullNotNullNotNull)
|
||||
b.noBoundsNotNull(aNotNullNotNullNull)
|
||||
b.noBoundsNotNull(aNotNullNullNotNull)
|
||||
b.noBoundsNotNull(aNotNullNullNull)
|
||||
|
||||
b.noBoundsNullable(aNotNullNotNullNotNull)
|
||||
b.noBoundsNullable(aNotNullNotNullNull)
|
||||
b.noBoundsNullable(aNotNullNullNotNull)
|
||||
b.noBoundsNullable(aNotNullNullNull)
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// JSPECIFY_STATE: strict
|
||||
// MUTE_FOR_PSI_CLASS_FILES_READING
|
||||
|
||||
@@ -24,14 +25,12 @@ fun main(
|
||||
b: WildcardsWithDefault
|
||||
): Unit {
|
||||
b.noBoundsNotNull(aNotNullNotNullNotNull)
|
||||
// jspecify_nullness_mismatch
|
||||
b.noBoundsNotNull(<!TYPE_MISMATCH!>aNotNullNotNullNull<!>)
|
||||
b.noBoundsNotNull(aNotNullNotNullNull)
|
||||
b.noBoundsNotNull(aNotNullNullNotNull)
|
||||
// jspecify_nullness_mismatch
|
||||
b.noBoundsNotNull(<!TYPE_MISMATCH!>aNotNullNullNull<!>)
|
||||
b.noBoundsNotNull(aNotNullNullNull)
|
||||
|
||||
b.noBoundsNullable(aNotNullNotNullNotNull)
|
||||
b.noBoundsNullable(aNotNullNotNullNull)
|
||||
b.noBoundsNullable(aNotNullNullNotNull)
|
||||
b.noBoundsNullable(aNotNullNullNull)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ public open class A</*0*/ T : kotlin.Any!, /*1*/ E, /*2*/ F : @org.jspecify.null
|
||||
public constructor WildcardsWithDefault()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open fun noBoundsNotNull(/*0*/ a: A<out kotlin.Any, *, out @org.jspecify.nullness.NullnessUnspecified kotlin.Any>): kotlin.Unit
|
||||
public open fun noBoundsNotNull(/*0*/ a: A<*, *, *>): kotlin.Unit
|
||||
public open fun noBoundsNullable(/*0*/ a: A<out @org.jspecify.nullness.Nullable kotlin.Any?, out @org.jspecify.nullness.Nullable kotlin.Any?, out @org.jspecify.nullness.Nullable kotlin.Any?>): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
// JSPECIFY_STATE: warn
|
||||
// MUTE_FOR_PSI_CLASS_FILES_READING
|
||||
|
||||
// FILE: WildcardsWithDefault.java
|
||||
import org.jspecify.nullness.*;
|
||||
|
||||
@NullMarked
|
||||
public class WildcardsWithDefault {
|
||||
public void noBoundsNotNull(A<?, ?, ?> a) {}
|
||||
public void noBoundsNullable(A<? extends @Nullable Object, ? extends @Nullable Object, ? extends @Nullable Object> a) {}
|
||||
}
|
||||
|
||||
// FILE: A.java
|
||||
import org.jspecify.nullness.*;
|
||||
|
||||
public class A <T extends Object, E extends @Nullable Object, F extends @NullnessUnspecified Object> {}
|
||||
|
||||
// FILE: main.kt
|
||||
fun main(
|
||||
aNotNullNotNullNotNull: A<Any, Any, Any>,
|
||||
aNotNullNotNullNull: A<Any, Any, Any?>,
|
||||
aNotNullNullNotNull: A<Any, Any?, Any>,
|
||||
aNotNullNullNull: A<Any, Any?, Any?>,
|
||||
b: WildcardsWithDefault
|
||||
): Unit {
|
||||
b.noBoundsNotNull(aNotNullNotNullNotNull)
|
||||
b.noBoundsNotNull(aNotNullNotNullNull)
|
||||
b.noBoundsNotNull(aNotNullNullNotNull)
|
||||
b.noBoundsNotNull(aNotNullNullNull)
|
||||
|
||||
b.noBoundsNullable(aNotNullNotNullNotNull)
|
||||
b.noBoundsNullable(aNotNullNotNullNull)
|
||||
b.noBoundsNullable(aNotNullNullNotNull)
|
||||
b.noBoundsNullable(aNotNullNullNull)
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// JSPECIFY_STATE: warn
|
||||
// MUTE_FOR_PSI_CLASS_FILES_READING
|
||||
|
||||
@@ -24,14 +25,12 @@ fun main(
|
||||
b: WildcardsWithDefault
|
||||
): Unit {
|
||||
b.noBoundsNotNull(aNotNullNotNullNotNull)
|
||||
// jspecify_nullness_mismatch
|
||||
b.noBoundsNotNull(<!NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS!>aNotNullNotNullNull<!>)
|
||||
b.noBoundsNotNull(aNotNullNotNullNull)
|
||||
b.noBoundsNotNull(aNotNullNullNotNull)
|
||||
// jspecify_nullness_mismatch
|
||||
b.noBoundsNotNull(<!NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS!>aNotNullNullNull<!>)
|
||||
b.noBoundsNotNull(aNotNullNullNull)
|
||||
|
||||
b.noBoundsNullable(aNotNullNotNullNotNull)
|
||||
b.noBoundsNullable(aNotNullNotNullNull)
|
||||
b.noBoundsNullable(aNotNullNullNotNull)
|
||||
b.noBoundsNullable(aNotNullNullNull)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,8 @@ import org.jetbrains.kotlin.name.FqName
|
||||
data class JavaDefaultQualifiers(
|
||||
val nullabilityQualifier: NullabilityQualifierWithMigrationStatus,
|
||||
val qualifierApplicabilityTypes: Collection<AnnotationQualifierApplicabilityType>,
|
||||
val affectsTypeParameterBasedTypes: Boolean = nullabilityQualifier.qualifier == NullabilityQualifier.NOT_NULL
|
||||
val affectsTypeParameterBasedTypes: Boolean = nullabilityQualifier.qualifier == NullabilityQualifier.NOT_NULL,
|
||||
val affectsStarProjection: Boolean = affectsTypeParameterBasedTypes
|
||||
) {
|
||||
val makesTypeParameterNotNull get() = nullabilityQualifier.qualifier == NullabilityQualifier.NOT_NULL && affectsTypeParameterBasedTypes
|
||||
}
|
||||
@@ -35,7 +36,8 @@ val JSPECIFY_DEFAULT_ANNOTATIONS = mapOf(
|
||||
JSPECIFY_NULL_MARKED to JavaDefaultQualifiers(
|
||||
NullabilityQualifierWithMigrationStatus(NullabilityQualifier.NOT_NULL),
|
||||
DEFAULT_JSPECIFY_APPLICABILITY,
|
||||
affectsTypeParameterBasedTypes = false
|
||||
affectsTypeParameterBasedTypes = false,
|
||||
affectsStarProjection = false
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
@@ -317,6 +317,12 @@ class SignatureEnhancement(
|
||||
typeParameterForArgument: TypeParameterDescriptor?,
|
||||
isFromStarProjection: Boolean
|
||||
): JavaTypeQualifiers {
|
||||
if (isFromStarProjection && typeParameterForArgument?.variance == Variance.IN_VARIANCE) {
|
||||
// Star projections can only be enhanced in one way: `?` -> `? extends <something>`. Given a Kotlin type `C<in T>
|
||||
// (declaration-site variance), this is not a valid enhancement due to conflicting variances.
|
||||
return JavaTypeQualifiers.NONE
|
||||
}
|
||||
|
||||
val areImprovementsInStrictMode = containerContext.components.settings.typeEnhancementImprovementsInStrictMode
|
||||
|
||||
val composedAnnotation =
|
||||
@@ -349,7 +355,7 @@ class SignatureEnhancement(
|
||||
containerContext.defaultTypeQualifiers?.get(containerApplicabilityType)
|
||||
else
|
||||
defaultQualifiersForType)?.takeIf {
|
||||
it.affectsTypeParameterBasedTypes || !isTypeParameter()
|
||||
(it.affectsTypeParameterBasedTypes || !isTypeParameter()) && (it.affectsStarProjection || !isFromStarProjection)
|
||||
}
|
||||
|
||||
val (nullabilityFromBoundsForTypeBasedOnTypeParameter, isTypeParameterWithNotNullableBounds) =
|
||||
@@ -362,8 +368,7 @@ class SignatureEnhancement(
|
||||
?: computeNullabilityInfoInTheAbsenceOfExplicitAnnotation(
|
||||
nullabilityFromBoundsForTypeBasedOnTypeParameter,
|
||||
defaultTypeQualifier,
|
||||
typeParameterForArgument,
|
||||
isFromStarProjection
|
||||
typeParameterForArgument
|
||||
)
|
||||
|
||||
val isNotNullTypeParameter =
|
||||
@@ -390,8 +395,7 @@ class SignatureEnhancement(
|
||||
private fun computeNullabilityInfoInTheAbsenceOfExplicitAnnotation(
|
||||
nullabilityFromBoundsForTypeBasedOnTypeParameter: NullabilityQualifierWithMigrationStatus?,
|
||||
defaultTypeQualifier: JavaDefaultQualifiers?,
|
||||
typeParameterForArgument: TypeParameterDescriptor?,
|
||||
isFromStarProjection: Boolean
|
||||
typeParameterForArgument: TypeParameterDescriptor?
|
||||
): NullabilityQualifierWithMigrationStatus? {
|
||||
|
||||
val result =
|
||||
@@ -412,7 +416,7 @@ class SignatureEnhancement(
|
||||
)
|
||||
}
|
||||
|
||||
if (result == null || isFromStarProjection) return boundsFromTypeParameterForArgument
|
||||
if (result == null) return boundsFromTypeParameterForArgument
|
||||
|
||||
return mostSpecific(boundsFromTypeParameterForArgument, result)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user