[FIR] Implement warnings for java nullability upper bound violation
This commit is contained in:
committed by
Space Team
parent
2df1e9dde6
commit
a63ec9efdc
+16
@@ -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,
|
||||
|
||||
+12
@@ -3523,6 +3523,18 @@ sealed interface KtFirDiagnostic<PSI : PsiElement> : KtDiagnosticWithPsi<PSI> {
|
||||
override val diagnosticClass get() = UpperBoundCannotBeArray::class
|
||||
}
|
||||
|
||||
interface UpperBoundViolatedBasedOnJavaAnnotations : KtFirDiagnostic<PsiElement> {
|
||||
override val diagnosticClass get() = UpperBoundViolatedBasedOnJavaAnnotations::class
|
||||
val expectedUpperBound: KtType
|
||||
val actualUpperBound: KtType
|
||||
}
|
||||
|
||||
interface UpperBoundViolatedInTypealiasExpansionBasedOnJavaAnnotations : KtFirDiagnostic<PsiElement> {
|
||||
override val diagnosticClass get() = UpperBoundViolatedInTypealiasExpansionBasedOnJavaAnnotations::class
|
||||
val expectedUpperBound: KtType
|
||||
val actualUpperBound: KtType
|
||||
}
|
||||
|
||||
interface StrictfpOnClass : KtFirDiagnostic<KtAnnotationEntry> {
|
||||
override val diagnosticClass get() = StrictfpOnClass::class
|
||||
}
|
||||
|
||||
+14
@@ -4250,6 +4250,20 @@ internal class UpperBoundCannotBeArrayImpl(
|
||||
token: KtLifetimeToken,
|
||||
) : KtAbstractFirDiagnostic<PsiElement>(firDiagnostic, token), KtFirDiagnostic.UpperBoundCannotBeArray
|
||||
|
||||
internal class UpperBoundViolatedBasedOnJavaAnnotationsImpl(
|
||||
override val expectedUpperBound: KtType,
|
||||
override val actualUpperBound: KtType,
|
||||
firDiagnostic: KtPsiDiagnostic,
|
||||
token: KtLifetimeToken,
|
||||
) : KtAbstractFirDiagnostic<PsiElement>(firDiagnostic, token), KtFirDiagnostic.UpperBoundViolatedBasedOnJavaAnnotations
|
||||
|
||||
internal class UpperBoundViolatedInTypealiasExpansionBasedOnJavaAnnotationsImpl(
|
||||
override val expectedUpperBound: KtType,
|
||||
override val actualUpperBound: KtType,
|
||||
firDiagnostic: KtPsiDiagnostic,
|
||||
token: KtLifetimeToken,
|
||||
) : KtAbstractFirDiagnostic<PsiElement>(firDiagnostic, token), KtFirDiagnostic.UpperBoundViolatedInTypealiasExpansionBasedOnJavaAnnotations
|
||||
|
||||
internal class StrictfpOnClassImpl(
|
||||
firDiagnostic: KtPsiDiagnostic,
|
||||
token: KtLifetimeToken,
|
||||
|
||||
+8
@@ -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<PsiElement>()
|
||||
val UPPER_BOUND_VIOLATED_BASED_ON_JAVA_ANNOTATIONS by warning<PsiElement> {
|
||||
parameter<ConeKotlinType>("expectedUpperBound")
|
||||
parameter<ConeKotlinType>("actualUpperBound")
|
||||
}
|
||||
val UPPER_BOUND_VIOLATED_IN_TYPEALIAS_EXPANSION_BASED_ON_JAVA_ANNOTATIONS by warning<PsiElement> {
|
||||
parameter<ConeKotlinType>("expectedUpperBound")
|
||||
parameter<ConeKotlinType>("actualUpperBound")
|
||||
}
|
||||
}
|
||||
|
||||
val ANNOTATIONS by object : DiagnosticGroup("annotations") {
|
||||
|
||||
+2
@@ -50,6 +50,8 @@ object FirJvmErrors {
|
||||
|
||||
// Type parameters
|
||||
val UPPER_BOUND_CANNOT_BE_ARRAY by error0<PsiElement>()
|
||||
val UPPER_BOUND_VIOLATED_BASED_ON_JAVA_ANNOTATIONS by warning2<PsiElement, ConeKotlinType, ConeKotlinType>()
|
||||
val UPPER_BOUND_VIOLATED_IN_TYPEALIAS_EXPANSION_BASED_ON_JAVA_ANNOTATIONS by warning2<PsiElement, ConeKotlinType, ConeKotlinType>()
|
||||
|
||||
// annotations
|
||||
val STRICTFP_ON_CLASS by error0<KtAnnotationEntry>()
|
||||
|
||||
+15
@@ -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.")
|
||||
|
||||
+29
@@ -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<ConeKotlinType, ConeKotlinType>
|
||||
get() = FirJvmErrors.UPPER_BOUND_VIOLATED_BASED_ON_JAVA_ANNOTATIONS
|
||||
|
||||
override val diagnosticForTypeAlias: KtDiagnosticFactory2<ConeKotlinType, ConeKotlinType>
|
||||
get() = FirJvmErrors.UPPER_BOUND_VIOLATED_IN_TYPEALIAS_EXPANSION_BASED_ON_JAVA_ANNOTATIONS
|
||||
|
||||
override fun getAdditionalUpperBound(coneKotlinType: ConeKotlinType): ConeKotlinType? {
|
||||
return substitutor.substituteOrNull(coneKotlinType)
|
||||
}
|
||||
}
|
||||
+28
@@ -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<ConeKotlinType, ConeKotlinType>
|
||||
val diagnosticForTypeAlias: KtDiagnosticFactory2<ConeKotlinType, ConeKotlinType>
|
||||
|
||||
fun getAdditionalUpperBound(coneKotlinType: ConeKotlinType): ConeKotlinType?
|
||||
}
|
||||
|
||||
val FirSession.platformUpperBoundsProvider: FirPlatformUpperBoundsProvider? by FirSession.nullableSessionComponentAccessor()
|
||||
|
||||
@@ -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 --------------------------
|
||||
|
||||
+2
-1
@@ -12,7 +12,8 @@ public class NullnessUnspecifiedTypeParameter<T> {
|
||||
public class Test {}
|
||||
|
||||
// FILE: main.kt
|
||||
fun main(a1: NullnessUnspecifiedTypeParameter<Any>, a2: NullnessUnspecifiedTypeParameter<Any?>, x: Test): Unit {
|
||||
// jspecify_nullness_mismatch
|
||||
fun main(a1: NullnessUnspecifiedTypeParameter<Any>, a2: NullnessUnspecifiedTypeParameter<<!UPPER_BOUND_VIOLATED_BASED_ON_JAVA_ANNOTATIONS!>Any?<!>>, x: Test): Unit {
|
||||
// jspecify_nullness_mismatch
|
||||
a1.foo(<!NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS!>null<!>)
|
||||
a1.foo(1)
|
||||
|
||||
+2
-1
@@ -13,7 +13,8 @@ public class NullnessUnspecifiedTypeParameter<T> {
|
||||
public class Test {}
|
||||
|
||||
// FILE: main.kt
|
||||
fun main(a1: NullnessUnspecifiedTypeParameter<Any>, a2: NullnessUnspecifiedTypeParameter<Any?>, x: Test): Unit {
|
||||
// jspecify_nullness_mismatch
|
||||
fun main(a1: NullnessUnspecifiedTypeParameter<Any>, a2: NullnessUnspecifiedTypeParameter<<!UPPER_BOUND_VIOLATED_BASED_ON_JAVA_ANNOTATIONS!>Any?<!>>, x: Test): Unit {
|
||||
// jspecify_nullness_mismatch
|
||||
a1.foo(<!NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS!>null<!>)
|
||||
a1.foo(1)
|
||||
|
||||
+10
-5
@@ -20,21 +20,26 @@ public class B<T> {
|
||||
public class Test {}
|
||||
|
||||
// FILE: main.kt
|
||||
fun <T : Test> main(a1: A<Any?>, a2: A<Test>, b1: B<Any?>, b2: B<Test>, x: T): Unit {
|
||||
// jspecify_nullness_mismatch, jspecify_nullness_mismatch
|
||||
fun <T : Test> main(a1: A<<!UPPER_BOUND_VIOLATED_BASED_ON_JAVA_ANNOTATIONS!>Any?<!>>, a2: A<Test>, b1: B<<!UPPER_BOUND_VIOLATED_BASED_ON_JAVA_ANNOTATIONS!>Any?<!>>, b2: B<Test>, x: T): Unit {
|
||||
a1.foo(null)
|
||||
a1.bar<T?>(null)
|
||||
// jspecify_nullness_mismatch
|
||||
a1.bar<<!UPPER_BOUND_VIOLATED_BASED_ON_JAVA_ANNOTATIONS!>T?<!>>(null)
|
||||
a1.bar<T>(x)
|
||||
|
||||
a2.foo(null)
|
||||
a2.bar<T?>(null)
|
||||
// jspecify_nullness_mismatch
|
||||
a2.bar<<!UPPER_BOUND_VIOLATED_BASED_ON_JAVA_ANNOTATIONS!>T?<!>>(null)
|
||||
a2.bar<T>(x)
|
||||
|
||||
b1.foo(null)
|
||||
b1.bar<T?>(null)
|
||||
// jspecify_nullness_mismatch
|
||||
b1.bar<<!UPPER_BOUND_VIOLATED_BASED_ON_JAVA_ANNOTATIONS!>T?<!>>(null)
|
||||
b1.bar<T>(x)
|
||||
|
||||
// jspecify_nullness_mismatch
|
||||
b2.foo(<!NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS!>null<!>)
|
||||
b2.bar<T?>(null)
|
||||
// jspecify_nullness_mismatch
|
||||
b2.bar<<!UPPER_BOUND_VIOLATED_BASED_ON_JAVA_ANNOTATIONS!>T?<!>>(null)
|
||||
b2.bar<T>(x)
|
||||
}
|
||||
|
||||
Vendored
+1
-1
@@ -13,7 +13,7 @@ public class Test {}
|
||||
|
||||
// FILE: main.kt
|
||||
// jspecify_nullness_mismatch
|
||||
fun main(a1: NullnessUnspecifiedTypeParameter<Any>, a2: NullnessUnspecifiedTypeParameter<Any?>, x: Test): Unit {
|
||||
fun main(a1: NullnessUnspecifiedTypeParameter<Any>, a2: NullnessUnspecifiedTypeParameter<<!UPPER_BOUND_VIOLATED_BASED_ON_JAVA_ANNOTATIONS!>Any?<!>>, x: Test): Unit {
|
||||
// jspecify_nullness_mismatch
|
||||
a1.foo(<!NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS!>null<!>)
|
||||
a1.foo(1)
|
||||
|
||||
+1
-1
@@ -14,7 +14,7 @@ public class Test {}
|
||||
|
||||
// FILE: main.kt
|
||||
// jspecify_nullness_mismatch
|
||||
fun main(a1: NullnessUnspecifiedTypeParameter<Any>, a2: NullnessUnspecifiedTypeParameter<Any?>, x: Test): Unit {
|
||||
fun main(a1: NullnessUnspecifiedTypeParameter<Any>, a2: NullnessUnspecifiedTypeParameter<<!UPPER_BOUND_VIOLATED_BASED_ON_JAVA_ANNOTATIONS!>Any?<!>>, x: Test): Unit {
|
||||
// jspecify_nullness_mismatch
|
||||
a1.foo(<!NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS!>null<!>)
|
||||
a1.foo(1)
|
||||
|
||||
+5
-5
@@ -21,26 +21,26 @@ public class Test {}
|
||||
|
||||
// FILE: main.kt
|
||||
// jspecify_nullness_mismatch, jspecify_nullness_mismatch
|
||||
fun <T : Test> main(a1: A<Any?>, a2: A<Test>, b1: B<Any?>, b2: B<Test>, x: T): Unit {
|
||||
fun <T : Test> main(a1: A<<!UPPER_BOUND_VIOLATED_BASED_ON_JAVA_ANNOTATIONS!>Any?<!>>, a2: A<Test>, b1: B<<!UPPER_BOUND_VIOLATED_BASED_ON_JAVA_ANNOTATIONS!>Any?<!>>, b2: B<Test>, x: T): Unit {
|
||||
a1.foo(null)
|
||||
// jspecify_nullness_mismatch
|
||||
a1.bar<T?>(null)
|
||||
a1.bar<<!UPPER_BOUND_VIOLATED_BASED_ON_JAVA_ANNOTATIONS!>T?<!>>(null)
|
||||
a1.bar<T>(x)
|
||||
|
||||
a2.foo(null)
|
||||
// jspecify_nullness_mismatch
|
||||
a2.bar<T?>(null)
|
||||
a2.bar<<!UPPER_BOUND_VIOLATED_BASED_ON_JAVA_ANNOTATIONS!>T?<!>>(null)
|
||||
a2.bar<T>(x)
|
||||
|
||||
// jspecify_nullness_mismatch
|
||||
b1.foo(null)
|
||||
// jspecify_nullness_mismatch
|
||||
b1.bar<T?>(null)
|
||||
b1.bar<<!UPPER_BOUND_VIOLATED_BASED_ON_JAVA_ANNOTATIONS!>T?<!>>(null)
|
||||
b1.bar<T>(x)
|
||||
|
||||
// jspecify_nullness_mismatch
|
||||
b2.foo(<!NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS!>null<!>)
|
||||
// jspecify_nullness_mismatch
|
||||
b2.bar<T?>(null)
|
||||
b2.bar<<!UPPER_BOUND_VIOLATED_BASED_ON_JAVA_ANNOTATIONS!>T?<!>>(null)
|
||||
b2.bar<T>(x)
|
||||
}
|
||||
|
||||
@@ -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<Any?>() // violated nullability, no warnings; but there is an error with -Xtype-enhancement-improvements-strict-mode
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// MUTE_FOR_PSI_CLASS_FILES_READING
|
||||
// SKIP_TXT
|
||||
|
||||
|
||||
+1
@@ -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",
|
||||
|
||||
Reference in New Issue
Block a user