K2/Java/enhancement: implement wildcards replacement with flexible bounds

This commit in fact changes two very related places:
- first, it implements forgotten 'enhancedForWarnings' in K2 enhancement
- second, it repeats KT-48515 fix for K2 while enhancing wildcards

#KT-65594 Fixed
Related to KT-48515, KT-63746
This commit is contained in:
Mikhail Glukhikh
2024-03-14 12:23:43 +01:00
committed by Space Team
parent 5b0cb5c9db
commit 40c4e865c7
25 changed files with 62 additions and 399 deletions
@@ -1,34 +0,0 @@
// FILE: NullnessUnspecifiedTypeParameter.java
import org.jspecify.annotations.*;
@NullMarked
public class NullnessUnspecifiedTypeParameter<T> {
public void foo(T t) {}
public void bar(Test s, T t) {} // t should not become not nullable
}
// FILE: Test.java
public class Test {}
// FILE: main.kt
// 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)
a2.foo(null)
a2.foo(1)
// jspecify_nullness_mismatch, jspecify_nullness_mismatch
a1.bar(<!NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS!>null<!>, <!NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS!>null<!>)
// jspecify_nullness_mismatch
a1.bar(x, <!NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS!>null<!>)
a1.bar(x, 1)
// jspecify_nullness_mismatch
a2.bar(<!NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS!>null<!>, null)
a2.bar(x, null)
a2.bar(x, 1)
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// FILE: NullnessUnspecifiedTypeParameter.java
import org.jspecify.annotations.*;
@@ -1,20 +0,0 @@
// JSPECIFY_STATE: strict
// FILE: Box.java
import org.jspecify.annotations.*;
@NullMarked
public class Box<V extends @Nullable Object> {
public static <V extends @Nullable Object> Box<V> make() {
return new Box<>();
}
}
// FILE: Util.java
public final class Util {
public Box<?> boxId(Box<?> box) { return box; }
}
// FILE: a.kt
fun foo(u: Util) =
u.boxId(Box.<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>make<!>())
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// JSPECIFY_STATE: strict
// FILE: Box.java
@@ -1,18 +0,0 @@
// JSPECIFY_STATE: strict
// !LANGUAGE: +TypeEnhancementImprovementsInStrictMode
// FILE: J1.java
import org.jspecify.annotations.*;
@NullMarked
public interface J1<T extends @Nullable Object> {
T foo();
}
// FILE: J2.java
public interface J2 {
J1<?> bar();
}
// FILE: main.kt
fun baz(j2: J2): Any = <!RETURN_TYPE_MISMATCH!>j2.bar().foo()<!> // Any..Any?
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// JSPECIFY_STATE: strict
// !LANGUAGE: +TypeEnhancementImprovementsInStrictMode
@@ -1,20 +0,0 @@
// JSPECIFY_STATE: warn
// FILE: Box.java
import org.jspecify.annotations.*;
@NullMarked
public class Box<V extends @Nullable Object> {
public static <V extends @Nullable Object> Box<V> make() {
return new Box<>();
}
}
// FILE: Util.java
public final class Util {
public Box<?> boxId(Box<?> box) { return box; }
}
// FILE: a.kt
fun foo(u: Util) =
u.boxId(Box.<!NEW_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>make<!>())
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// JSPECIFY_STATE: warn
// FILE: Box.java
@@ -1,35 +0,0 @@
// JSPECIFY_STATE: warn
// FILE: NullnessUnspecifiedTypeParameter.java
import org.jspecify.annotations.*;
@NullMarked
public class NullnessUnspecifiedTypeParameter<T> {
public void foo(T t) {}
public void bar(Test s, T t) {} // t should not become not nullable
}
// FILE: Test.java
public class Test {}
// FILE: main.kt
// 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)
a2.foo(null)
a2.foo(1)
// jspecify_nullness_mismatch, jspecify_nullness_mismatch
a1.bar(<!NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS!>null<!>, <!NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS!>null<!>)
// jspecify_nullness_mismatch
a1.bar(x, <!NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS!>null<!>)
a1.bar(x, 1)
// jspecify_nullness_mismatch
a2.bar(<!NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS!>null<!>, null)
a2.bar(x, null)
a2.bar(x, 1)
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// JSPECIFY_STATE: warn
// FILE: NullnessUnspecifiedTypeParameter.java
import org.jspecify.annotations.*;
@@ -40,15 +40,18 @@ public class CKN extends C<@Nullable CK> {}
// FILE: main.kt
fun main(ak: AK, akn: AKN, bk: BK, ck: CK, ckn: CKN): Unit {
ak.foo(ak)
ak.foo(null)
// jspecify_nullness_mismatch
ak.foo(<!NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS!>null<!>)
akn.foo(null) // the corresponding warning/error is present on the Java side
bk.foo(bk)
bk.foo(null)
// jspecify_nullness_mismatch
bk.foo(<!NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS!>null<!>)
ck.foo(ck)
ck.foo(null)
// jspecify_nullness_mismatch
ck.foo(<!NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS!>null<!>)
ckn.foo(null) // the corresponding warning/error is present on the Java side
}
@@ -23,19 +23,24 @@ public class Test {}
// 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<T?>(<!NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS!>null<!>)
a1.bar<T>(x)
a2.foo(null)
a2.bar<T?>(null)
// jspecify_nullness_mismatch
a2.bar<T?>(<!NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS!>null<!>)
a2.bar<T>(x)
b1.foo(null)
b1.bar<T?>(null)
// jspecify_nullness_mismatch
b1.foo(<!NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS!>null<!>)
// jspecify_nullness_mismatch
b1.bar<T?>(<!NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS!>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<T?>(<!NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS!>null<!>)
b2.bar<T>(x)
}