From afa1d18cc2f8f3d839b37c52a3f41e280d0bccfa Mon Sep 17 00:00:00 2001 From: pyos Date: Tue, 7 Sep 2021 11:30:02 +0200 Subject: [PATCH] FE: in NullMarked scope, enhance T! to at least T #KT-44436 Fixed --- .../jspecify/strictMode/SelfType.txt | 8 +++---- .../jspecify/strictMode/kt47422.txt | 3 ++- .../jspecify/strictMode/kt47437.fir.kt | 18 -------------- .../java8Tests/jspecify/strictMode/kt47437.kt | 3 ++- .../jspecify/strictMode/kt47437.txt | 3 ++- .../java8Tests/jspecify/warnMode/SelfType.txt | 2 +- .../load/java/AnnotationQualifiersFqNames.kt | 4 ++-- .../typeEnhancement/AbstractSignatureParts.kt | 24 +++++++------------ .../java/typeEnhancement/typeQualifiers.kt | 2 +- 9 files changed, 23 insertions(+), 44 deletions(-) delete mode 100644 compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/strictMode/kt47437.fir.kt diff --git a/compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/strictMode/SelfType.txt b/compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/strictMode/SelfType.txt index 772fe2f87b7..876a46667ac 100644 --- a/compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/strictMode/SelfType.txt +++ b/compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/strictMode/SelfType.txt @@ -34,8 +34,8 @@ public open class BK : B { public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String } -@org.jspecify.nullness.NullMarked public open class C> : SelfType { - public constructor C>() +@org.jspecify.nullness.NullMarked public open class C> : SelfType { + public constructor C>() public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean public open override /*1*/ /*fake_override*/ fun foo(/*0*/ t: E): kotlin.Unit public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int @@ -58,8 +58,8 @@ public open class CKN : C<@org.jspecify.nullness.Nullable CK?> { public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String } -@org.jspecify.nullness.NullMarked public open class SelfType> { - public constructor SelfType>() +@org.jspecify.nullness.NullMarked public open class SelfType> { + public constructor SelfType>() public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean public open fun foo(/*0*/ t: T): kotlin.Unit public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int diff --git a/compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/strictMode/kt47422.txt b/compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/strictMode/kt47422.txt index a0dc8368cef..38dfd8a110e 100644 --- a/compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/strictMode/kt47422.txt +++ b/compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/strictMode/kt47422.txt @@ -82,5 +82,6 @@ public open class UtilGenericNullnessUnspecifiedBound { public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String // Static members - public open fun getFooOfK(): Foo + public open fun getFooOfK(): Foo } + diff --git a/compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/strictMode/kt47437.fir.kt b/compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/strictMode/kt47437.fir.kt deleted file mode 100644 index f17605c72dc..00000000000 --- a/compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/strictMode/kt47437.fir.kt +++ /dev/null @@ -1,18 +0,0 @@ -// JSPECIFY_STATE: strict -// !LANGUAGE: +TypeEnhancementImprovementsInStrictMode -// MUTE_FOR_PSI_CLASS_FILES_READING - -// FILE: Foo.java -import org.jspecify.nullness.*; - -@NullMarked -public class Foo { - static Foo create() { - return new Foo<>(); - } -} - -// FILE: main.kt -fun test(): Foo { - return ")!>Foo.create() -} diff --git a/compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/strictMode/kt47437.kt b/compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/strictMode/kt47437.kt index 4cc3afe614e..cea3e05bba3 100644 --- a/compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/strictMode/kt47437.kt +++ b/compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/strictMode/kt47437.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // JSPECIFY_STATE: strict // !LANGUAGE: +TypeEnhancementImprovementsInStrictMode // MUTE_FOR_PSI_CLASS_FILES_READING @@ -14,5 +15,5 @@ public class Foo { // FILE: main.kt fun test(): Foo { - return ")!>Foo.create() + return ")!>Foo.create() } diff --git a/compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/strictMode/kt47437.txt b/compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/strictMode/kt47437.txt index 8639509c4a1..da6e80b8960 100644 --- a/compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/strictMode/kt47437.txt +++ b/compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/strictMode/kt47437.txt @@ -9,5 +9,6 @@ public fun test(): Foo public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String // Static members - public/*package*/ open fun ..kotlin.Comparable?)> create(): Foo + public/*package*/ open fun ..kotlin.Comparable?)> create(): Foo } + diff --git a/compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/warnMode/SelfType.txt b/compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/warnMode/SelfType.txt index be8558b2e1f..2436f6496f6 100644 --- a/compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/warnMode/SelfType.txt +++ b/compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/warnMode/SelfType.txt @@ -34,7 +34,7 @@ public open class BK : B { public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String } -@org.jspecify.nullness.NullMarked public open class C!> : SelfType { +@org.jspecify.nullness.NullMarked public open class C!> : SelfType { public constructor C!>() public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean public open override /*1*/ /*fake_override*/ fun foo(/*0*/ t: E!): kotlin.Unit diff --git a/core/compiler.common.jvm/src/org/jetbrains/kotlin/load/java/AnnotationQualifiersFqNames.kt b/core/compiler.common.jvm/src/org/jetbrains/kotlin/load/java/AnnotationQualifiersFqNames.kt index 288b28e5242..4acf719d0f0 100644 --- a/core/compiler.common.jvm/src/org/jetbrains/kotlin/load/java/AnnotationQualifiersFqNames.kt +++ b/core/compiler.common.jvm/src/org/jetbrains/kotlin/load/java/AnnotationQualifiersFqNames.kt @@ -12,7 +12,7 @@ import org.jetbrains.kotlin.name.FqName data class JavaDefaultQualifiers( val nullabilityQualifier: NullabilityQualifierWithMigrationStatus, val qualifierApplicabilityTypes: Collection, - val affectsTypeParameterBasedTypes: Boolean = nullabilityQualifier.qualifier == NullabilityQualifier.NOT_NULL + val definitelyNotNull: Boolean = nullabilityQualifier.qualifier == NullabilityQualifier.NOT_NULL ) val TYPE_QUALIFIER_NICKNAME_FQNAME = FqName("javax.annotation.meta.TypeQualifierNickname") @@ -33,7 +33,7 @@ val JSPECIFY_DEFAULT_ANNOTATIONS = mapOf( JSPECIFY_NULL_MARKED to JavaDefaultQualifiers( NullabilityQualifierWithMigrationStatus(NullabilityQualifier.NOT_NULL), DEFAULT_JSPECIFY_APPLICABILITY, - affectsTypeParameterBasedTypes = false + definitelyNotNull = false ) ) diff --git a/core/compiler.common.jvm/src/org/jetbrains/kotlin/load/java/typeEnhancement/AbstractSignatureParts.kt b/core/compiler.common.jvm/src/org/jetbrains/kotlin/load/java/typeEnhancement/AbstractSignatureParts.kt index c0cea008a83..90bac36b65c 100644 --- a/core/compiler.common.jvm/src/org/jetbrains/kotlin/load/java/typeEnhancement/AbstractSignatureParts.kt +++ b/core/compiler.common.jvm/src/org/jetbrains/kotlin/load/java/typeEnhancement/AbstractSignatureParts.kt @@ -104,7 +104,6 @@ abstract class AbstractSignatureParts { else -> AnnotationQualifierApplicabilityType.TYPE_USE } val defaultTypeQualifier = defaultQualifiers?.get(applicabilityType) - ?.takeIf { (it.affectsTypeParameterBasedTypes || typeParameterUse == null) } val referencedParameterBoundsNullability = typeParameterUse?.boundsNullability // For type parameter uses, we have *three* options: @@ -112,7 +111,7 @@ abstract class AbstractSignatureParts { // happens if T is bounded by @NotNull (technically !! is redundant) or context says unannotated // type parameters are non-null; // T - NOT_NULL, isNotNullTypeParameter = false - // happens if T is bounded by @Nullable or context says unannotated types in general are non-null; + // happens if T is bounded by @Nullable (should it?) or context says unannotated types in general are non-null; // T? - NULLABLE, isNotNullTypeParameter = false // happens if context says unannotated types in general are nullable. // For other types, this is more straightforward (just take nullability from the context). @@ -122,27 +121,22 @@ abstract class AbstractSignatureParts { ?: defaultTypeQualifier?.nullabilityQualifier val definitelyNotNull = referencedParameterBoundsNullability?.qualifier == NullabilityQualifier.NOT_NULL || - (typeParameterUse != null && defaultTypeQualifier?.nullabilityQualifier?.qualifier == NullabilityQualifier.NOT_NULL) + (typeParameterUse != null && defaultTypeQualifier?.definitelyNotNull == true) // We should also enhance this type to satisfy the bound of the type parameter it is instantiating: // for C, C becomes C regardless of the above. val substitutedParameterBoundsNullability = typeParameterForArgument?.boundsNullability - val result = when { - substitutedParameterBoundsNullability == null -> defaultNullability - defaultNullability == null -> - if (substitutedParameterBoundsNullability.qualifier == NullabilityQualifier.NULLABLE) - substitutedParameterBoundsNullability.copy(qualifier = NullabilityQualifier.FORCE_FLEXIBILITY) - else - substitutedParameterBoundsNullability - else -> mostSpecific(substitutedParameterBoundsNullability, defaultNullability) - } + ?.let { if (it.qualifier == NullabilityQualifier.NULLABLE) it.copy(qualifier = NullabilityQualifier.FORCE_FLEXIBILITY) else it } + val result = mostSpecific(substitutedParameterBoundsNullability, defaultNullability) return JavaTypeQualifiers(result?.qualifier, annotationsMutability, definitelyNotNull, result?.isForWarningOnly == true) } private fun mostSpecific( - a: NullabilityQualifierWithMigrationStatus, - b: NullabilityQualifierWithMigrationStatus - ): NullabilityQualifierWithMigrationStatus { + a: NullabilityQualifierWithMigrationStatus?, + b: NullabilityQualifierWithMigrationStatus? + ): NullabilityQualifierWithMigrationStatus? { + if (a == null) return b + if (b == null) return a // TODO: this probably behaves really weirdly when some of those are warnings. if (a.qualifier == NullabilityQualifier.FORCE_FLEXIBILITY) return b if (b.qualifier == NullabilityQualifier.FORCE_FLEXIBILITY) return a diff --git a/core/compiler.common.jvm/src/org/jetbrains/kotlin/load/java/typeEnhancement/typeQualifiers.kt b/core/compiler.common.jvm/src/org/jetbrains/kotlin/load/java/typeEnhancement/typeQualifiers.kt index 0879b05383f..0e1d5bf16db 100644 --- a/core/compiler.common.jvm/src/org/jetbrains/kotlin/load/java/typeEnhancement/typeQualifiers.kt +++ b/core/compiler.common.jvm/src/org/jetbrains/kotlin/load/java/typeEnhancement/typeQualifiers.kt @@ -16,7 +16,7 @@ enum class MutabilityQualifier { MUTABLE } -class JavaTypeQualifiers constructor( +class JavaTypeQualifiers( val nullability: NullabilityQualifier?, val mutability: MutabilityQualifier?, val definitelyNotNull: Boolean,