[FIR] Fix lower bound of flexible type variable not becoming DNN in warning-severity case

The bug was introduced as part of the implementation for Java
nullability warnings.

#KT-58933 Fixed
This commit is contained in:
Kirill Rakhman
2023-11-20 13:44:00 +01:00
committed by Space Team
parent 711e7ce8d7
commit 31256e259e
7 changed files with 47 additions and 33 deletions
@@ -1,17 +0,0 @@
// JSPECIFY_STATE: warn
// 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
// jspecify_nullness_mismatch
fun baz(j2: J2): Any = <!NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS!>j2.bar().foo()<!> // Any..Any?
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// JSPECIFY_STATE: warn
// FILE: J1.java
import org.jspecify.annotations.*;
@@ -1,16 +0,0 @@
// JSPECIFY_STATE: warn
// FILE: J1.java
import org.jspecify.nullness.*;
@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 = <!NULLABILITY_MISMATCH_BASED_ON_JAVA_ANNOTATIONS!>j2.bar().foo()<!> // Any..Any?
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// JSPECIFY_STATE: warn
// FILE: J1.java
import org.jspecify.nullness.*;
@@ -62,3 +62,23 @@ abstract class A<T> : Provider<T> {
<!WRONG_NULLABILITY_FOR_JAVA_OVERRIDE!>override<!> fun getSet(x: T): T = x
<!NOTHING_TO_OVERRIDE!>override<!> fun getSetNullable(x: T): T = x
}
abstract class B<T> : Provider<T> {
override fun get(): T & Any = null!!
override fun getNullable(): T? = null!!
override fun set(x: T & Any) {} // False positive in K1
override fun setNullable(x: T?) {}
override fun getSet(x: T & Any): T & Any = x // False positive in K1
override fun getSetNullable(x: T?): T? = x
}
abstract class C<T> : Provider<T> {
<!WRONG_NULLABILITY_FOR_JAVA_OVERRIDE!>override<!> fun getSet(x: T): T & Any = x!! // Missing warning in K1, K2 get's this right
<!NOTHING_TO_OVERRIDE!>override<!> fun getSetNullable(x: T): T? = x
}
abstract class D<T> : Provider<T> {
<!WRONG_NULLABILITY_FOR_JAVA_OVERRIDE!>override<!> fun getSet(x: T & Any): T = x<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!> // False positive in K1
override fun getSetNullable(x: T?): T = x!!
}
@@ -62,3 +62,23 @@ abstract class A<T> : Provider<T> {
<!WRONG_NULLABILITY_FOR_JAVA_OVERRIDE!>override<!> fun getSet(x: T): T = x
<!NOTHING_TO_OVERRIDE!>override<!> fun getSetNullable(x: T): T = x
}
abstract class B<T> : Provider<T> {
override fun get(): T & Any = null!!
override fun getNullable(): T? = null!!
<!NOTHING_TO_OVERRIDE!>override<!> fun set(x: T & Any) {} // False positive in K1
override fun setNullable(x: T?) {}
<!NOTHING_TO_OVERRIDE!>override<!> fun getSet(x: T & Any): T & Any = x // False positive in K1
override fun getSetNullable(x: T?): T? = x
}
abstract class C<T> : Provider<T> {
override fun getSet(x: T): T & Any = x!! // Missing warning in K1, K2 get's this right
<!NOTHING_TO_OVERRIDE!>override<!> fun getSetNullable(x: T): T? = x
}
abstract class D<T> : Provider<T> {
<!NOTHING_TO_OVERRIDE!>override<!> fun getSet(x: T & Any): T = x<!UNNECESSARY_NOT_NULL_ASSERTION!>!!<!> // False positive in K1
override fun getSetNullable(x: T?): T = x!!
}