From a63ec9efdce213579f4aee08928a4e04ebe88c12 Mon Sep 17 00:00:00 2001 From: Kirill Rakhman Date: Thu, 21 Sep 2023 10:29:45 +0200 Subject: [PATCH] [FIR] Implement warnings for java nullability upper bound violation --- .../diagnostics/KtFirDataClassConverters.kt | 16 ++++++++++ .../api/fir/diagnostics/KtFirDiagnostics.kt | 12 ++++++++ .../fir/diagnostics/KtFirDiagnosticsImpl.kt | 14 +++++++++ .../diagnostics/FirJvmDiagnosticsList.kt | 8 +++++ .../analysis/diagnostics/jvm/FirJvmErrors.kt | 2 ++ .../jvm/FirJvmErrorsDefaultMessages.kt | 15 ++++++++++ ...vaNullabilityWarningUpperBoundsProvider.kt | 29 +++++++++++++++++++ .../checkers/FirUpperBoundViolatedHelpers.kt | 28 ++++++++++++++++++ .../fir/session/ComponentsContainers.kt | 3 ++ .../java8Tests/jspecify/default.fir.kt | 3 +- .../NullnessUnspecifiedTypeParameter.fir.kt | 3 +- .../warnMode/TypeParameterBounds.fir.kt | 15 ++++++---- .../java8Tests/jspecifyOld/default.fir.kt | 2 +- .../NullnessUnspecifiedTypeParameter.fir.kt | 2 +- .../warnMode/TypeParameterBounds.fir.kt | 10 +++---- .../tests/kt47920.fir.kt | 12 -------- .../foreignAnnotationsTests/tests/kt47920.kt | 1 + .../JspecifyDiagnosticComplianceHandler.kt | 1 + 18 files changed, 150 insertions(+), 26 deletions(-) create mode 100644 compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/FirJavaNullabilityWarningUpperBoundsProvider.kt delete mode 100644 compiler/testData/diagnostics/foreignAnnotationsTests/tests/kt47920.fir.kt diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDataClassConverters.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDataClassConverters.kt index 0ae3af72601..f13ae2cb22b 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDataClassConverters.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDataClassConverters.kt @@ -5063,6 +5063,22 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert token, ) } + add(FirJvmErrors.UPPER_BOUND_VIOLATED_BASED_ON_JAVA_ANNOTATIONS) { firDiagnostic -> + UpperBoundViolatedBasedOnJavaAnnotationsImpl( + firSymbolBuilder.typeBuilder.buildKtType(firDiagnostic.a), + firSymbolBuilder.typeBuilder.buildKtType(firDiagnostic.b), + firDiagnostic as KtPsiDiagnostic, + token, + ) + } + add(FirJvmErrors.UPPER_BOUND_VIOLATED_IN_TYPEALIAS_EXPANSION_BASED_ON_JAVA_ANNOTATIONS) { firDiagnostic -> + UpperBoundViolatedInTypealiasExpansionBasedOnJavaAnnotationsImpl( + firSymbolBuilder.typeBuilder.buildKtType(firDiagnostic.a), + firSymbolBuilder.typeBuilder.buildKtType(firDiagnostic.b), + firDiagnostic as KtPsiDiagnostic, + token, + ) + } add(FirJvmErrors.STRICTFP_ON_CLASS) { firDiagnostic -> StrictfpOnClassImpl( firDiagnostic as KtPsiDiagnostic, diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnostics.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnostics.kt index 29427d1db70..ea797a25e0f 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnostics.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnostics.kt @@ -3523,6 +3523,18 @@ sealed interface KtFirDiagnostic : KtDiagnosticWithPsi { override val diagnosticClass get() = UpperBoundCannotBeArray::class } + interface UpperBoundViolatedBasedOnJavaAnnotations : KtFirDiagnostic { + override val diagnosticClass get() = UpperBoundViolatedBasedOnJavaAnnotations::class + val expectedUpperBound: KtType + val actualUpperBound: KtType + } + + interface UpperBoundViolatedInTypealiasExpansionBasedOnJavaAnnotations : KtFirDiagnostic { + override val diagnosticClass get() = UpperBoundViolatedInTypealiasExpansionBasedOnJavaAnnotations::class + val expectedUpperBound: KtType + val actualUpperBound: KtType + } + interface StrictfpOnClass : KtFirDiagnostic { override val diagnosticClass get() = StrictfpOnClass::class } diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnosticsImpl.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnosticsImpl.kt index baa8a15e9ad..dd3c9e17783 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnosticsImpl.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/diagnostics/KtFirDiagnosticsImpl.kt @@ -4250,6 +4250,20 @@ internal class UpperBoundCannotBeArrayImpl( token: KtLifetimeToken, ) : KtAbstractFirDiagnostic(firDiagnostic, token), KtFirDiagnostic.UpperBoundCannotBeArray +internal class UpperBoundViolatedBasedOnJavaAnnotationsImpl( + override val expectedUpperBound: KtType, + override val actualUpperBound: KtType, + firDiagnostic: KtPsiDiagnostic, + token: KtLifetimeToken, +) : KtAbstractFirDiagnostic(firDiagnostic, token), KtFirDiagnostic.UpperBoundViolatedBasedOnJavaAnnotations + +internal class UpperBoundViolatedInTypealiasExpansionBasedOnJavaAnnotationsImpl( + override val expectedUpperBound: KtType, + override val actualUpperBound: KtType, + firDiagnostic: KtPsiDiagnostic, + token: KtLifetimeToken, +) : KtAbstractFirDiagnostic(firDiagnostic, token), KtFirDiagnostic.UpperBoundViolatedInTypealiasExpansionBasedOnJavaAnnotations + internal class StrictfpOnClassImpl( firDiagnostic: KtPsiDiagnostic, token: KtLifetimeToken, diff --git a/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirJvmDiagnosticsList.kt b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirJvmDiagnosticsList.kt index 679160d51fc..cde95e25f7d 100644 --- a/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirJvmDiagnosticsList.kt +++ b/compiler/fir/checkers/checkers-component-generator/src/org/jetbrains/kotlin/fir/checkers/generator/diagnostics/FirJvmDiagnosticsList.kt @@ -64,6 +64,14 @@ object JVM_DIAGNOSTICS_LIST : DiagnosticList("FirJvmErrors") { val TYPE_PARAMETERS by object : DiagnosticGroup("Type parameters") { val UPPER_BOUND_CANNOT_BE_ARRAY by error() + val UPPER_BOUND_VIOLATED_BASED_ON_JAVA_ANNOTATIONS by warning { + parameter("expectedUpperBound") + parameter("actualUpperBound") + } + val UPPER_BOUND_VIOLATED_IN_TYPEALIAS_EXPANSION_BASED_ON_JAVA_ANNOTATIONS by warning { + parameter("expectedUpperBound") + parameter("actualUpperBound") + } } val ANNOTATIONS by object : DiagnosticGroup("annotations") { diff --git a/compiler/fir/checkers/checkers.jvm/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/jvm/FirJvmErrors.kt b/compiler/fir/checkers/checkers.jvm/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/jvm/FirJvmErrors.kt index a73ca7134e9..aa7e478446c 100644 --- a/compiler/fir/checkers/checkers.jvm/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/jvm/FirJvmErrors.kt +++ b/compiler/fir/checkers/checkers.jvm/gen/org/jetbrains/kotlin/fir/analysis/diagnostics/jvm/FirJvmErrors.kt @@ -50,6 +50,8 @@ object FirJvmErrors { // Type parameters val UPPER_BOUND_CANNOT_BE_ARRAY by error0() + val UPPER_BOUND_VIOLATED_BASED_ON_JAVA_ANNOTATIONS by warning2() + val UPPER_BOUND_VIOLATED_IN_TYPEALIAS_EXPANSION_BASED_ON_JAVA_ANNOTATIONS by warning2() // annotations val STRICTFP_ON_CLASS by error0() diff --git a/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/diagnostics/jvm/FirJvmErrorsDefaultMessages.kt b/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/diagnostics/jvm/FirJvmErrorsDefaultMessages.kt index 99aa0a4646f..10b5b441b78 100644 --- a/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/diagnostics/jvm/FirJvmErrorsDefaultMessages.kt +++ b/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/diagnostics/jvm/FirJvmErrorsDefaultMessages.kt @@ -80,6 +80,8 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.SYNCHRONIZ import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.SYNCHRONIZED_ON_INLINE import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.SYNCHRONIZED_ON_SUSPEND import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.UPPER_BOUND_CANNOT_BE_ARRAY +import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.UPPER_BOUND_VIOLATED_BASED_ON_JAVA_ANNOTATIONS +import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.UPPER_BOUND_VIOLATED_IN_TYPEALIAS_EXPANSION_BASED_ON_JAVA_ANNOTATIONS import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.VALUE_CLASS_WITHOUT_JVM_INLINE_ANNOTATION import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors.WRONG_NULLABILITY_FOR_JAVA_OVERRIDE @@ -108,6 +110,19 @@ object FirJvmErrorsDefaultMessages : BaseDiagnosticRendererFactory() { SYMBOL, ) + map.put( + UPPER_BOUND_VIOLATED_BASED_ON_JAVA_ANNOTATIONS, + "Type argument is not within its bounds: should be subtype of ''{0}''.", + RENDER_TYPE, + RENDER_TYPE + ) + map.put( + UPPER_BOUND_VIOLATED_IN_TYPEALIAS_EXPANSION_BASED_ON_JAVA_ANNOTATIONS, + "Type argument is not within its bounds: should be subtype of ''{0}''.", + RENDER_TYPE, + RENDER_TYPE + ) + map.put(UPPER_BOUND_CANNOT_BE_ARRAY, "Upper bound of type parameter cannot be an array.") map.put(STRICTFP_ON_CLASS, "'@Strictfp' annotation on classes is not yet supported.") map.put(SYNCHRONIZED_ON_ABSTRACT, "'@Synchronized' annotation cannot be used on abstract functions.") diff --git a/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/FirJavaNullabilityWarningUpperBoundsProvider.kt b/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/FirJavaNullabilityWarningUpperBoundsProvider.kt new file mode 100644 index 00000000000..f9957336636 --- /dev/null +++ b/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/FirJavaNullabilityWarningUpperBoundsProvider.kt @@ -0,0 +1,29 @@ +/* + * Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.fir.analysis.jvm.checkers + +import org.jetbrains.kotlin.diagnostics.KtDiagnosticFactory2 +import org.jetbrains.kotlin.fir.FirSession +import org.jetbrains.kotlin.fir.analysis.checkers.FirPlatformUpperBoundsProvider +import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors +import org.jetbrains.kotlin.fir.java.enhancement.EnhancedForWarningConeSubstitutor +import org.jetbrains.kotlin.fir.java.enhancement.enhancedTypeForWarning +import org.jetbrains.kotlin.fir.types.ConeKotlinType +import org.jetbrains.kotlin.fir.types.typeContext + +class FirJavaNullabilityWarningUpperBoundsProvider(session: FirSession) : FirPlatformUpperBoundsProvider { + private val substitutor: EnhancedForWarningConeSubstitutor = EnhancedForWarningConeSubstitutor(session.typeContext) + + override val diagnostic: KtDiagnosticFactory2 + get() = FirJvmErrors.UPPER_BOUND_VIOLATED_BASED_ON_JAVA_ANNOTATIONS + + override val diagnosticForTypeAlias: KtDiagnosticFactory2 + get() = FirJvmErrors.UPPER_BOUND_VIOLATED_IN_TYPEALIAS_EXPANSION_BASED_ON_JAVA_ANNOTATIONS + + override fun getAdditionalUpperBound(coneKotlinType: ConeKotlinType): ConeKotlinType? { + return substitutor.substituteOrNull(coneKotlinType) + } +} \ No newline at end of file diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/FirUpperBoundViolatedHelpers.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/FirUpperBoundViolatedHelpers.kt index f15eb2c8729..723c041954e 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/FirUpperBoundViolatedHelpers.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/FirUpperBoundViolatedHelpers.kt @@ -7,8 +7,10 @@ package org.jetbrains.kotlin.fir.analysis.checkers import org.jetbrains.kotlin.KtSourceElement import org.jetbrains.kotlin.diagnostics.DiagnosticReporter +import org.jetbrains.kotlin.diagnostics.KtDiagnosticFactory2 import org.jetbrains.kotlin.diagnostics.reportOn import org.jetbrains.kotlin.fir.FirSession +import org.jetbrains.kotlin.fir.FirSessionComponent import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors import org.jetbrains.kotlin.fir.resolve.fullyExpandedType @@ -179,6 +181,7 @@ fun checkUpperBoundViolated( ) { val count = minOf(typeParameters.size, typeArguments.size) val typeSystemContext = context.session.typeContext + val additionalUpperBoundsProvider = context.session.platformUpperBoundsProvider for (index in 0 until count) { val argument = typeArguments[index] @@ -204,6 +207,22 @@ fun checkUpperBoundViolated( else -> FirErrors.UPPER_BOUND_VIOLATED } reporter.reportOn(argumentSource, factory, upperBound, argumentType.type, context) + } else { + // Only check if the original check was successful to prevent duplicate diagnostics + val additionalUpperBound = additionalUpperBoundsProvider?.getAdditionalUpperBound(upperBound) + if (additionalUpperBound != null && !AbstractTypeChecker.isSubtypeOf( + typeSystemContext, + argumentType, + additionalUpperBound, + stubTypesEqualToAnything = true + ) + ) { + val factory = when { + isReportExpansionError && argumentTypeRef == null -> additionalUpperBoundsProvider.diagnosticForTypeAlias + else -> additionalUpperBoundsProvider.diagnostic + } + reporter.reportOn(argumentSource, factory, upperBound, argumentType.type, context) + } } } @@ -262,3 +281,12 @@ fun ConeTypeProjection.withSource(source: FirTypeRefSource?): ConeTypeProjection } } } + +interface FirPlatformUpperBoundsProvider : FirSessionComponent { + val diagnostic: KtDiagnosticFactory2 + val diagnosticForTypeAlias: KtDiagnosticFactory2 + + fun getAdditionalUpperBound(coneKotlinType: ConeKotlinType): ConeKotlinType? +} + +val FirSession.platformUpperBoundsProvider: FirPlatformUpperBoundsProvider? by FirSession.nullableSessionComponentAccessor() diff --git a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/ComponentsContainers.kt b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/ComponentsContainers.kt index 98ed045e2b8..21b2f4a8988 100644 --- a/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/ComponentsContainers.kt +++ b/compiler/fir/entrypoint/src/org/jetbrains/kotlin/fir/session/ComponentsContainers.kt @@ -12,10 +12,12 @@ import org.jetbrains.kotlin.fir.* import org.jetbrains.kotlin.fir.analysis.CheckersComponent import org.jetbrains.kotlin.fir.analysis.FirOverridesBackwardCompatibilityHelper import org.jetbrains.kotlin.fir.analysis.checkers.FirInlineCheckerPlatformSpecificComponent +import org.jetbrains.kotlin.fir.analysis.checkers.FirPlatformUpperBoundsProvider import org.jetbrains.kotlin.fir.analysis.checkers.FirPrimaryConstructorSuperTypeCheckerPlatformComponent import org.jetbrains.kotlin.fir.analysis.checkers.declaration.FirNameConflictsTracker import org.jetbrains.kotlin.fir.analysis.checkers.expression.FirGenericArrayClassLiteralSupport import org.jetbrains.kotlin.fir.analysis.jvm.FirJvmOverridesBackwardCompatibilityHelper +import org.jetbrains.kotlin.fir.analysis.jvm.checkers.FirJavaNullabilityWarningUpperBoundsProvider import org.jetbrains.kotlin.fir.analysis.jvm.checkers.FirJvmAnnotationsPlatformSpecificSupportComponent import org.jetbrains.kotlin.fir.analysis.jvm.checkers.FirJvmInlineCheckerComponent import org.jetbrains.kotlin.fir.analysis.jvm.checkers.FirJvmPrimaryConstructorSuperTypeCheckerPlatformComponent @@ -162,6 +164,7 @@ fun FirSession.registerJavaComponents( register(FirInlineCheckerPlatformSpecificComponent::class, FirJvmInlineCheckerComponent()) register(FirGenericArrayClassLiteralSupport::class, FirGenericArrayClassLiteralSupport.Enabled) register(FirDelegatedMembersFilter::class, FirJvmDelegatedMembersFilter(this)) + register(FirPlatformUpperBoundsProvider::class, FirJavaNullabilityWarningUpperBoundsProvider(this)) } // -------------------------- Resolve components -------------------------- diff --git a/compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/default.fir.kt b/compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/default.fir.kt index 757cc1d5d00..b5be33deeba 100644 --- a/compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/default.fir.kt +++ b/compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/default.fir.kt @@ -12,7 +12,8 @@ public class NullnessUnspecifiedTypeParameter { public class Test {} // FILE: main.kt -fun main(a1: NullnessUnspecifiedTypeParameter, a2: NullnessUnspecifiedTypeParameter, x: Test): Unit { +// jspecify_nullness_mismatch +fun main(a1: NullnessUnspecifiedTypeParameter, a2: NullnessUnspecifiedTypeParameter<Any?>, x: Test): Unit { // jspecify_nullness_mismatch a1.foo(null) a1.foo(1) diff --git a/compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/warnMode/NullnessUnspecifiedTypeParameter.fir.kt b/compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/warnMode/NullnessUnspecifiedTypeParameter.fir.kt index dc0f4ab799b..ea7fcb7f579 100644 --- a/compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/warnMode/NullnessUnspecifiedTypeParameter.fir.kt +++ b/compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/warnMode/NullnessUnspecifiedTypeParameter.fir.kt @@ -13,7 +13,8 @@ public class NullnessUnspecifiedTypeParameter { public class Test {} // FILE: main.kt -fun main(a1: NullnessUnspecifiedTypeParameter, a2: NullnessUnspecifiedTypeParameter, x: Test): Unit { +// jspecify_nullness_mismatch +fun main(a1: NullnessUnspecifiedTypeParameter, a2: NullnessUnspecifiedTypeParameter<Any?>, x: Test): Unit { // jspecify_nullness_mismatch a1.foo(null) a1.foo(1) diff --git a/compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/warnMode/TypeParameterBounds.fir.kt b/compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/warnMode/TypeParameterBounds.fir.kt index 8b98f8360f7..6b765d5a3cc 100644 --- a/compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/warnMode/TypeParameterBounds.fir.kt +++ b/compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/warnMode/TypeParameterBounds.fir.kt @@ -20,21 +20,26 @@ public class B { public class Test {} // FILE: main.kt -fun main(a1: A, a2: A, b1: B, b2: B, x: T): Unit { +// jspecify_nullness_mismatch, jspecify_nullness_mismatch +fun main(a1: A<Any?>, a2: A, b1: B<Any?>, b2: B, x: T): Unit { a1.foo(null) - a1.bar(null) + // jspecify_nullness_mismatch + a1.bar<T?>(null) a1.bar(x) a2.foo(null) - a2.bar(null) + // jspecify_nullness_mismatch + a2.bar<T?>(null) a2.bar(x) b1.foo(null) - b1.bar(null) + // jspecify_nullness_mismatch + b1.bar<T?>(null) b1.bar(x) // jspecify_nullness_mismatch b2.foo(null) - b2.bar(null) + // jspecify_nullness_mismatch + b2.bar<T?>(null) b2.bar(x) } diff --git a/compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecifyOld/default.fir.kt b/compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecifyOld/default.fir.kt index fc030585b3a..930bdf0bac8 100644 --- a/compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecifyOld/default.fir.kt +++ b/compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecifyOld/default.fir.kt @@ -13,7 +13,7 @@ public class Test {} // FILE: main.kt // jspecify_nullness_mismatch -fun main(a1: NullnessUnspecifiedTypeParameter, a2: NullnessUnspecifiedTypeParameter, x: Test): Unit { +fun main(a1: NullnessUnspecifiedTypeParameter, a2: NullnessUnspecifiedTypeParameter<Any?>, x: Test): Unit { // jspecify_nullness_mismatch a1.foo(null) a1.foo(1) diff --git a/compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecifyOld/warnMode/NullnessUnspecifiedTypeParameter.fir.kt b/compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecifyOld/warnMode/NullnessUnspecifiedTypeParameter.fir.kt index 04c42247af6..e36c47ac722 100644 --- a/compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecifyOld/warnMode/NullnessUnspecifiedTypeParameter.fir.kt +++ b/compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecifyOld/warnMode/NullnessUnspecifiedTypeParameter.fir.kt @@ -14,7 +14,7 @@ public class Test {} // FILE: main.kt // jspecify_nullness_mismatch -fun main(a1: NullnessUnspecifiedTypeParameter, a2: NullnessUnspecifiedTypeParameter, x: Test): Unit { +fun main(a1: NullnessUnspecifiedTypeParameter, a2: NullnessUnspecifiedTypeParameter<Any?>, x: Test): Unit { // jspecify_nullness_mismatch a1.foo(null) a1.foo(1) diff --git a/compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecifyOld/warnMode/TypeParameterBounds.fir.kt b/compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecifyOld/warnMode/TypeParameterBounds.fir.kt index 53164eda7d9..588d76a9f4e 100644 --- a/compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecifyOld/warnMode/TypeParameterBounds.fir.kt +++ b/compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecifyOld/warnMode/TypeParameterBounds.fir.kt @@ -21,26 +21,26 @@ public class Test {} // FILE: main.kt // jspecify_nullness_mismatch, jspecify_nullness_mismatch -fun main(a1: A, a2: A, b1: B, b2: B, x: T): Unit { +fun main(a1: A<Any?>, a2: A, b1: B<Any?>, b2: B, x: T): Unit { a1.foo(null) // jspecify_nullness_mismatch - a1.bar(null) + a1.bar<T?>(null) a1.bar(x) a2.foo(null) // jspecify_nullness_mismatch - a2.bar(null) + a2.bar<T?>(null) a2.bar(x) // jspecify_nullness_mismatch b1.foo(null) // jspecify_nullness_mismatch - b1.bar(null) + b1.bar<T?>(null) b1.bar(x) // jspecify_nullness_mismatch b2.foo(null) // jspecify_nullness_mismatch - b2.bar(null) + b2.bar<T?>(null) b2.bar(x) } diff --git a/compiler/testData/diagnostics/foreignAnnotationsTests/tests/kt47920.fir.kt b/compiler/testData/diagnostics/foreignAnnotationsTests/tests/kt47920.fir.kt deleted file mode 100644 index 1db54b20b14..00000000000 --- a/compiler/testData/diagnostics/foreignAnnotationsTests/tests/kt47920.fir.kt +++ /dev/null @@ -1,12 +0,0 @@ -// MUTE_FOR_PSI_CLASS_FILES_READING -// SKIP_TXT - -// FILE: J1.java -import io.reactivex.rxjava3.annotations.*; - -public class J1<@NonNull T> {} - -// FILE: main.kt -fun main() { - J1() // violated nullability, no warnings; but there is an error with -Xtype-enhancement-improvements-strict-mode -} diff --git a/compiler/testData/diagnostics/foreignAnnotationsTests/tests/kt47920.kt b/compiler/testData/diagnostics/foreignAnnotationsTests/tests/kt47920.kt index aa920319afc..0622d795e35 100644 --- a/compiler/testData/diagnostics/foreignAnnotationsTests/tests/kt47920.kt +++ b/compiler/testData/diagnostics/foreignAnnotationsTests/tests/kt47920.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // MUTE_FOR_PSI_CLASS_FILES_READING // SKIP_TXT diff --git a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/frontend/classic/handlers/JspecifyDiagnosticComplianceHandler.kt b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/frontend/classic/handlers/JspecifyDiagnosticComplianceHandler.kt index 2eea7332408..ec937172c51 100644 --- a/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/frontend/classic/handlers/JspecifyDiagnosticComplianceHandler.kt +++ b/compiler/tests-common-new/tests/org/jetbrains/kotlin/test/frontend/classic/handlers/JspecifyDiagnosticComplianceHandler.kt @@ -57,6 +57,7 @@ internal val diagnosticsToJspecifyMarks = mapOf( FirJvmErrors.NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS to "jspecify_nullness_mismatch", FirJvmErrors.RECEIVER_NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS to "jspecify_nullness_mismatch", + FirJvmErrors.UPPER_BOUND_VIOLATED_BASED_ON_JAVA_ANNOTATIONS to "jspecify_nullness_mismatch", ), ReportLevel.STRICT to mapOf( Errors.TYPE_MISMATCH to "jspecify_nullness_mismatch",