FIR: enhance Java type parameter bounds
This also fixes handling of self-recursive types.
TODO: fix jspecify/{strict,warn}Mode/Captured.fir.kt
This commit is contained in:
compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/jspecify/strictMode/Captured.fir.kt
Vendored
+17
@@ -0,0 +1,17 @@
|
||||
// JSPECIFY_STATE: strict
|
||||
// !LANGUAGE: +TypeEnhancementImprovementsInStrictMode
|
||||
// FILE: J1.java
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public interface J1<T> {
|
||||
@Nullable
|
||||
public static <T> T foo(J1<T> x) { return null; }
|
||||
}
|
||||
|
||||
// FILE: J2.java
|
||||
import org.jspecify.nullness.Nullable;
|
||||
|
||||
public interface J2<V extends @Nullable Object> extends J1<V> { }
|
||||
|
||||
// FILE: kotlin.kt
|
||||
private fun J2<*>.bar() = <!NEW_INFERENCE_ERROR!>J1.foo(this)<!>
|
||||
Vendored
-1
@@ -1,4 +1,3 @@
|
||||
// FIR_IDENTICAL
|
||||
// JSPECIFY_STATE: strict
|
||||
// !LANGUAGE: +TypeEnhancementImprovementsInStrictMode
|
||||
// FILE: J1.java
|
||||
|
||||
-27
@@ -1,27 +0,0 @@
|
||||
// !LANGUAGE: +ProhibitUsingNullableTypeParameterAgainstNotNullAnnotated +TypeEnhancementImprovementsInStrictMode
|
||||
// JSPECIFY_STATE: strict
|
||||
// MUTE_FOR_PSI_CLASS_FILES_READING
|
||||
|
||||
// FILE: NonPlatformTypeParameter.java
|
||||
import org.jspecify.nullness.*;
|
||||
|
||||
public class NonPlatformTypeParameter<T extends @Nullable Object> {
|
||||
public void foo(T t) {}
|
||||
public <E extends @Nullable Object> void bar(E e) {}
|
||||
}
|
||||
|
||||
// FILE: Test.java
|
||||
public class Test {}
|
||||
|
||||
// FILE: main.kt
|
||||
fun <T : Test> main(a1: NonPlatformTypeParameter<Any?>, a2: NonPlatformTypeParameter<Test>, x: T): Unit {
|
||||
a1.foo(null)
|
||||
a1.bar<Test?>(null)
|
||||
a1.bar<T>(null)
|
||||
a1.bar<T>(x)
|
||||
|
||||
a2.foo(null)
|
||||
a2.bar<Test?>(null)
|
||||
a2.bar<T>(null)
|
||||
a2.bar<T>(x)
|
||||
}
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// FIR_IDENTICAL
|
||||
// !LANGUAGE: +ProhibitUsingNullableTypeParameterAgainstNotNullAnnotated +TypeEnhancementImprovementsInStrictMode
|
||||
// JSPECIFY_STATE: strict
|
||||
// MUTE_FOR_PSI_CLASS_FILES_READING
|
||||
|
||||
+7
-4
@@ -14,16 +14,19 @@ public class NullnessUnspecifiedTypeParameter<T> {
|
||||
public class Test {}
|
||||
|
||||
// FILE: main.kt
|
||||
fun main(a1: NullnessUnspecifiedTypeParameter<Any>, a2: NullnessUnspecifiedTypeParameter<Any?>, x: Test): Unit {
|
||||
a1.foo(null)
|
||||
// jspecify_nullness_mismatch
|
||||
fun main(a1: NullnessUnspecifiedTypeParameter<Any>, a2: NullnessUnspecifiedTypeParameter<<!UPPER_BOUND_VIOLATED!>Any?<!>>, x: Test): Unit {
|
||||
// jspecify_nullness_mismatch
|
||||
a1.foo(<!NULL_FOR_NONNULL_TYPE!>null<!>)
|
||||
a1.foo(1)
|
||||
|
||||
a2.foo(null)
|
||||
a2.foo(1)
|
||||
|
||||
// jspecify_nullness_mismatch, jspecify_nullness_mismatch
|
||||
a1.bar(<!NULL_FOR_NONNULL_TYPE!>null<!>, <!NULL_FOR_NONNULL_TYPE!>null<!>)
|
||||
// jspecify_nullness_mismatch
|
||||
a1.bar(<!NULL_FOR_NONNULL_TYPE!>null<!>, null)
|
||||
a1.bar(x, null)
|
||||
a1.bar(x, <!NULL_FOR_NONNULL_TYPE!>null<!>)
|
||||
a1.bar(x, 1)
|
||||
|
||||
// jspecify_nullness_mismatch
|
||||
|
||||
+12
-6
@@ -21,20 +21,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!>Any?<!>>, a2: A<Test>, b1: B<<!UPPER_BOUND_VIOLATED!>Any?<!>>, b2: B<Test>, x: T): Unit {
|
||||
a1.foo(null)
|
||||
a1.bar<T?>(null)
|
||||
// jspecify_nullness_mismatch, jspecify_nullness_mismatch
|
||||
a1.bar<<!UPPER_BOUND_VIOLATED!>T?<!>>(<!NULL_FOR_NONNULL_TYPE!>null<!>)
|
||||
a1.bar<T>(x)
|
||||
|
||||
a2.foo(null)
|
||||
a2.bar<T?>(null)
|
||||
// jspecify_nullness_mismatch, jspecify_nullness_mismatch
|
||||
a2.bar<<!UPPER_BOUND_VIOLATED!>T?<!>>(<!NULL_FOR_NONNULL_TYPE!>null<!>)
|
||||
a2.bar<T>(x)
|
||||
|
||||
b1.foo(null)
|
||||
b1.bar<T?>(null)
|
||||
// jspecify_nullness_mismatch, jspecify_nullness_mismatch
|
||||
b1.bar<<!UPPER_BOUND_VIOLATED!>T?<!>>(<!NULL_FOR_NONNULL_TYPE!>null<!>)
|
||||
b1.bar<T>(x)
|
||||
|
||||
b2.foo(null)
|
||||
b2.bar<T?>(null)
|
||||
// jspecify_nullness_mismatch
|
||||
b2.foo(<!NULL_FOR_NONNULL_TYPE!>null<!>)
|
||||
// jspecify_nullness_mismatch, jspecify_nullness_mismatch
|
||||
b2.bar<<!UPPER_BOUND_VIOLATED!>T?<!>>(<!NULL_FOR_NONNULL_TYPE!>null<!>)
|
||||
b2.bar<T>(x)
|
||||
}
|
||||
|
||||
Vendored
+2
-1
@@ -99,7 +99,8 @@ fun test3() {
|
||||
// String in Foo is not null
|
||||
isNotNullAndNullableStringInFoo(
|
||||
UtilNullMarkedGeneric.getFooOfK(),
|
||||
UtilNullMarkedGeneric.getFooOfK()
|
||||
// jspecify_nullness_mismatch
|
||||
<!ARGUMENT_TYPE_MISMATCH!>UtilNullMarkedGeneric.getFooOfK()<!>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
Vendored
+1
-1
@@ -14,5 +14,5 @@ public class Foo<T extends @Nullable Object> {
|
||||
|
||||
// FILE: main.kt
|
||||
fun test(): Foo<String> {
|
||||
return <!DEBUG_INFO_EXPRESSION_TYPE("Foo<kotlin.String..kotlin.String?!>")!>Foo.create()<!>
|
||||
return <!DEBUG_INFO_EXPRESSION_TYPE("Foo<kotlin.String>")!>Foo.create()<!>
|
||||
}
|
||||
|
||||
Vendored
+17
@@ -0,0 +1,17 @@
|
||||
// JSPECIFY_STATE: warn
|
||||
// !LANGUAGE: +TypeEnhancementImprovementsInStrictMode
|
||||
// FILE: J1.java
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public interface J1<T> {
|
||||
@Nullable
|
||||
public static <T> T foo(J1<T> x) { return null; }
|
||||
}
|
||||
|
||||
// FILE: J2.java
|
||||
import org.jspecify.nullness.Nullable;
|
||||
|
||||
public interface J2<V extends @Nullable Object> extends J1<V> { }
|
||||
|
||||
// FILE: kotlin.kt
|
||||
private fun J2<*>.bar() = <!NEW_INFERENCE_ERROR!>J1.foo(this)<!>
|
||||
Vendored
+1
-2
@@ -1,4 +1,3 @@
|
||||
// FIR_IDENTICAL
|
||||
// JSPECIFY_STATE: warn
|
||||
// !LANGUAGE: +TypeEnhancementImprovementsInStrictMode
|
||||
// FILE: J1.java
|
||||
@@ -15,4 +14,4 @@ import org.jspecify.nullness.Nullable;
|
||||
public interface J2<V extends @Nullable Object> extends J1<V> { }
|
||||
|
||||
// FILE: kotlin.kt
|
||||
private fun J2<*>.bar() = J1.foo(this)
|
||||
private fun J2<*>.bar() = J1.foo(this)
|
||||
|
||||
+3
-3
@@ -17,11 +17,11 @@ public class Test {}
|
||||
fun <T : Test> main(a1: NonPlatformTypeParameter<Any?>, a2: NonPlatformTypeParameter<Test>, x: T): Unit {
|
||||
a1.foo(null)
|
||||
a1.bar<Test?>(null)
|
||||
a1.bar<T>(null)
|
||||
a1.bar<T>(<!NULL_FOR_NONNULL_TYPE!>null<!>)
|
||||
a1.bar<T>(x)
|
||||
|
||||
a2.foo(null)
|
||||
a2.foo(<!NULL_FOR_NONNULL_TYPE!>null<!>)
|
||||
a2.bar<Test?>(null)
|
||||
a2.bar<T>(null)
|
||||
a2.bar<T>(<!NULL_FOR_NONNULL_TYPE!>null<!>)
|
||||
a2.bar<T>(x)
|
||||
}
|
||||
|
||||
+4
-4
@@ -13,15 +13,15 @@ public class NullnessUnspecifiedTypeParameter<T> {
|
||||
public class Test {}
|
||||
|
||||
// FILE: main.kt
|
||||
fun main(a1: NullnessUnspecifiedTypeParameter<Any>, a2: NullnessUnspecifiedTypeParameter<Any?>, x: Test): Unit {
|
||||
a1.foo(null)
|
||||
fun main(a1: NullnessUnspecifiedTypeParameter<Any>, a2: NullnessUnspecifiedTypeParameter<<!UPPER_BOUND_VIOLATED!>Any?<!>>, x: Test): Unit {
|
||||
a1.foo(<!NULL_FOR_NONNULL_TYPE!>null<!>)
|
||||
a1.foo(1)
|
||||
|
||||
a2.foo(null)
|
||||
a2.foo(1)
|
||||
|
||||
a1.bar(<!NULL_FOR_NONNULL_TYPE!>null<!>, null)
|
||||
a1.bar(x, null)
|
||||
a1.bar(<!NULL_FOR_NONNULL_TYPE!>null<!>, <!NULL_FOR_NONNULL_TYPE!>null<!>)
|
||||
a1.bar(x, <!NULL_FOR_NONNULL_TYPE!>null<!>)
|
||||
a1.bar(x, 1)
|
||||
|
||||
a2.bar(<!NULL_FOR_NONNULL_TYPE!>null<!>, null)
|
||||
|
||||
+6
-6
@@ -20,20 +20,20 @@ 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 {
|
||||
fun <T : Test> main(a1: A<<!UPPER_BOUND_VIOLATED!>Any?<!>>, a2: A<Test>, b1: B<<!UPPER_BOUND_VIOLATED!>Any?<!>>, b2: B<Test>, x: T): Unit {
|
||||
a1.foo(null)
|
||||
a1.bar<T?>(null)
|
||||
a1.bar<<!UPPER_BOUND_VIOLATED!>T?<!>>(<!NULL_FOR_NONNULL_TYPE!>null<!>)
|
||||
a1.bar<T>(x)
|
||||
|
||||
a2.foo(null)
|
||||
a2.bar<T?>(null)
|
||||
a2.bar<<!UPPER_BOUND_VIOLATED!>T?<!>>(<!NULL_FOR_NONNULL_TYPE!>null<!>)
|
||||
a2.bar<T>(x)
|
||||
|
||||
b1.foo(null)
|
||||
b1.bar<T?>(null)
|
||||
b1.bar<<!UPPER_BOUND_VIOLATED!>T?<!>>(<!NULL_FOR_NONNULL_TYPE!>null<!>)
|
||||
b1.bar<T>(x)
|
||||
|
||||
b2.foo(null)
|
||||
b2.bar<T?>(null)
|
||||
b2.foo(<!NULL_FOR_NONNULL_TYPE!>null<!>)
|
||||
b2.bar<<!UPPER_BOUND_VIOLATED!>T?<!>>(<!NULL_FOR_NONNULL_TYPE!>null<!>)
|
||||
b2.bar<T>(x)
|
||||
}
|
||||
|
||||
compiler/testData/diagnostics/foreignAnnotationsTests/java8Tests/misc/classTypeParameterBound.fir.kt
Vendored
+4
-4
@@ -13,13 +13,13 @@ public class ClassTypeParameterBound <T extends @NotNull String> {
|
||||
}
|
||||
|
||||
// FILE: main.kt
|
||||
fun main(x: ClassTypeParameterBound<String?>, y: ClassTypeParameterBound<String>, a: String?, b: String) {
|
||||
val x2 = ClassTypeParameterBound<String?>()
|
||||
fun main(x: ClassTypeParameterBound<<!UPPER_BOUND_VIOLATED!>String?<!>>, y: ClassTypeParameterBound<String>, a: String?, b: String) {
|
||||
val x2 = ClassTypeParameterBound<<!UPPER_BOUND_VIOLATED!>String?<!>>()
|
||||
val y2 = ClassTypeParameterBound<String>()
|
||||
|
||||
val x3 = ClassTypeParameterBound(a)
|
||||
val x3 = ClassTypeParameterBound(<!ARGUMENT_TYPE_MISMATCH!>a<!>)
|
||||
val y3 = ClassTypeParameterBound(b)
|
||||
|
||||
val x4: ClassTypeParameterBound<String?> = ClassTypeParameterBound()
|
||||
val x4: ClassTypeParameterBound<<!UPPER_BOUND_VIOLATED!>String?<!>> = <!TYPE_MISMATCH!>ClassTypeParameterBound()<!>
|
||||
val y4: ClassTypeParameterBound<String> = ClassTypeParameterBound()
|
||||
}
|
||||
|
||||
+4
-4
@@ -13,13 +13,13 @@ public class ClassTypeParameterBoundWithWarnings <T extends @NotNull String> {
|
||||
}
|
||||
|
||||
// FILE: main.kt
|
||||
fun main(x: ClassTypeParameterBoundWithWarnings<String?>, y: ClassTypeParameterBoundWithWarnings<String>, a: String?, b: String) {
|
||||
val x2 = ClassTypeParameterBoundWithWarnings<String?>()
|
||||
fun main(x: ClassTypeParameterBoundWithWarnings<<!UPPER_BOUND_VIOLATED!>String?<!>>, y: ClassTypeParameterBoundWithWarnings<String>, a: String?, b: String) {
|
||||
val x2 = ClassTypeParameterBoundWithWarnings<<!UPPER_BOUND_VIOLATED!>String?<!>>()
|
||||
val y2 = ClassTypeParameterBoundWithWarnings<String>()
|
||||
|
||||
val x3 = ClassTypeParameterBoundWithWarnings(a)
|
||||
val x3 = ClassTypeParameterBoundWithWarnings(<!ARGUMENT_TYPE_MISMATCH!>a<!>)
|
||||
val y3 = ClassTypeParameterBoundWithWarnings(b)
|
||||
|
||||
val x4: ClassTypeParameterBoundWithWarnings<String?> = ClassTypeParameterBoundWithWarnings()
|
||||
val x4: ClassTypeParameterBoundWithWarnings<<!UPPER_BOUND_VIOLATED!>String?<!>> = <!TYPE_MISMATCH!>ClassTypeParameterBoundWithWarnings()<!>
|
||||
val y4: ClassTypeParameterBoundWithWarnings<String> = ClassTypeParameterBoundWithWarnings()
|
||||
}
|
||||
|
||||
+1
-1
@@ -10,5 +10,5 @@ public interface MapLike<@org.jetbrains.annotations.NotNull K> {
|
||||
|
||||
// FILE: main.kt
|
||||
fun test2(map : MapLike<Int>, x2: Int?) {
|
||||
map.put(x2)
|
||||
map.put(<!ARGUMENT_TYPE_MISMATCH!>x2<!>)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user