FIR: Refine inference constraints when type variable in flexible position

That issue might be fixed via changing
TypeVariableMarker.shouldBeFlexible at ConeConstraintSystemUtilContext
but this and some other tricks have been added because of incorrect
handling of constraints where type variable has a flexible bound

^KT-51168 Fixed
This commit is contained in:
Denis.Zharkov
2022-04-12 16:30:55 +03:00
committed by teamcity
parent 853b7ec078
commit f70ae2df3a
54 changed files with 411 additions and 154 deletions
@@ -1,17 +0,0 @@
// 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)<!>
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// JSPECIFY_STATE: strict
// !LANGUAGE: +TypeEnhancementImprovementsInStrictMode
// FILE: J1.java
@@ -37,7 +37,7 @@ fun <R> main(a: ReturnType<R>) {
takeNullableStringAndKNullable(x1)
takeNotNullStringAndNotNullK(<!ARGUMENT_TYPE_MISMATCH!>x1<!>)
takeNullableStringAndNotNullK(<!ARGUMENT_TYPE_MISMATCH!>x1<!>)
takeNotNullString(<!ARGUMENT_TYPE_MISMATCH!>a.foo41.foo411<!>)
takeNotNullString(a.foo41.foo411)
val x2 = <!DEBUG_INFO_EXPRESSION_TYPE("ReturnType.A<kotlin.String?, R!!>..ReturnType.A<kotlin.String?, R!!>?!")!>a.foo2()<!>
takeNotNullStringAndKNullable(<!ARGUMENT_TYPE_MISMATCH!>x2<!>)
@@ -39,7 +39,7 @@ fun <R> main(a: ReturnTypeWithWarnings<R>) {
takeNullableStringAndKNullable(x1)
takeNotNullStringAndNotNullK(<!ARGUMENT_TYPE_MISMATCH!>x1<!>)
takeNullableStringAndNotNullK(<!ARGUMENT_TYPE_MISMATCH!>x1<!>)
takeNotNullString(<!ARGUMENT_TYPE_MISMATCH!>a.foo41.foo411<!>)
takeNotNullString(a.foo41.foo411)
val x2 = <!DEBUG_INFO_EXPRESSION_TYPE("ReturnTypeWithWarnings.A<kotlin.String?, R!!>..ReturnTypeWithWarnings.A<kotlin.String?, R!!>?!")!>a.foo2()<!>
takeNotNullStringAndKNullable(<!ARGUMENT_TYPE_MISMATCH!>x2<!>)
@@ -0,0 +1,42 @@
// !LANGUAGE: +DefinitelyNonNullableTypes +ProhibitUsingNullableTypeParameterAgainstNotNullAnnotated
// FILE: A.java
import org.jetbrains.annotations.*;
public interface A<T> {
public T foo(T x) { return x; }
@NotNull
public T bar(@NotNull T x) {}
}
// FILE: main.kt
interface B<T1> : A<T1> {
override fun foo(x: T1): T1
override fun bar(x: T1 & Any): T1 & Any
}
interface C<T2> : A<T2> {
override fun foo(x: T2 & Any): T2 & Any
<!NOTHING_TO_OVERRIDE!>override<!> fun bar(x: T2): T2
}
interface D : A<String?> {
override fun foo(x: String?): String?
override fun bar(x: String): String
}
interface E : A<String> {
override fun foo(x: String): String
override fun bar(x: String): String
}
interface F : A<String?> {
override fun foo(x: String): String
<!NOTHING_TO_OVERRIDE!>override<!> fun bar(x: String?): String?
}
interface G<T3 : Any> : A<T3> {
override fun foo(x: T3): T3
override fun bar(x: T3): T3
}
@@ -1,4 +1,3 @@
// FIR_IDENTICAL
// !LANGUAGE: +DefinitelyNonNullableTypes +ProhibitUsingNullableTypeParameterAgainstNotNullAnnotated
// FILE: A.java
@@ -27,7 +27,7 @@ val xExplicit: X = Test().findViewById(0)
val xCast = Test().findViewById(0) as X
val xCastExplicitType = Test().findViewById<X>(0) as X
val xSafeCastExplicitType = Test().findViewById<X>(0) as? X
val xSafeCastExplicitType = Test().findViewById<X>(0) <!USELESS_CAST!>as? X<!>
val yExplicit: Y<String> = Test().findViewById(0)
val yCast = Test().findViewById(0) as Y<String>
@@ -0,0 +1,20 @@
// SKIP_TXT
// FILE: JavaClass.java
public class JavaClass {
public static <K> K simpleId(K k) { // fun <K> simpleId(k: K & Any..K?): K & Any..K? =
return k;
}
}
// FILE: main.kt
fun takeN(n: Number?): Int = 1
fun bar(n: Number?) {
fun takeN(n: Number): String = ""
// in K1, it was resolved to nullable takeN
// in K2, it would be resolved to not-nullable and may fail with NPE
takeN(JavaClass.simpleId(n)).<!UNRESOLVED_REFERENCE!>div<!>(1)
takeN(JavaClass.simpleId(n)).length
}
@@ -0,0 +1,20 @@
// SKIP_TXT
// FILE: JavaClass.java
public class JavaClass {
public static <K> K simpleId(K k) { // fun <K> simpleId(k: K & Any..K?): K & Any..K? =
return k;
}
}
// FILE: main.kt
fun takeN(n: Number?): Int = 1
fun bar(n: Number?) {
fun takeN(n: Number): String = ""
// in K1, it was resolved to nullable takeN
// in K2, it would be resolved to not-nullable and may fail with NPE
takeN(JavaClass.simpleId(n)).div(1)
takeN(JavaClass.simpleId(n)).<!UNRESOLVED_REFERENCE!>length<!>
}
@@ -0,0 +1,11 @@
// FIR_IDENTICAL
// SKIP_TXT
// FILE: XBreakpointProperties.java
public abstract class XBreakpointProperties<T> {}
// FILE: XBreakpoint.java
public interface XBreakpoint<P extends XBreakpointProperties> {}
// FILE: XBreakpointType.java
public abstract class XBreakpointType<B extends XBreakpoint<P>, P extends XBreakpointProperties> {}
// FILE: main.kt
fun foo(x: XBreakpointType<XBreakpoint<*>, *>) {}
@@ -12,7 +12,7 @@ public class A {
fun test() {
A.bar(null, "")
A.bar<String>(null, "")
A.bar<String>(<!NULL_FOR_NONNULL_TYPE!>null<!>, "")
A.bar<String?>(null, "")
A.bar(null, A.platformString())
}
@@ -1,9 +0,0 @@
import java.util.ArrayList
fun foo() {
val list = ArrayList<String?>()
for (s in list) {
s.length
}
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
import java.util.ArrayList
fun foo() {
@@ -0,0 +1,20 @@
// FIR_IDENTICAL
// SKIP_TXT
// FILE: ExtensionPointName.java
public final class ExtensionPointName<T> {}
// FILE: ExtensionPoint.java
import org.jetbrains.annotations.NotNull;
public interface ExtensionPoint<@NotNull T> {
T foo();
}
// FILE: Area.java
public class Area {
@NotNull
public static <T> ExtensionPoint<T> getExtensionPoint(@NotNull ExtensionPointName<T> extensionPointName) { return null; }
}
// FILE: main.kt
private fun unregisterEverything(extensionPoint: ExtensionPointName<*>) {
Area.getExtensionPoint(extensionPoint).foo().hashCode()
}
File diff suppressed because one or more lines are too long
@@ -0,0 +1,36 @@
// FIR_IDENTICAL
// SKIP_TXT
// FILE: AbstractMapAssert.java
import java.util.Map;
public abstract class AbstractMapAssert<SELF extends AbstractMapAssert<SELF, ACTUAL, K, V>, ACTUAL extends Map<K, V>, K, V> {
public SELF isNotNull() {
return (SELF) this;
}
}
// FILE: MapAssert.java
import java.util.Map;
public class MapAssert<KEY, VALUE> extends AbstractMapAssert<MapAssert<KEY, VALUE>, Map<KEY, VALUE>, KEY, VALUE> {
public MapAssert(Map<KEY, VALUE> actual) {}
}
// FILE: Assertions.java
import java.util.Map;
public class Assertions {
public static <K, V> MapAssert<K, V> assertThat(Map<K, V> actual) {
return new MapAssert<>(actual);
}
}
// FILE: test.kt
fun <S : Map<*,*>> S?.must() {
Assertions.assertThat(this).isNotNull
}
@@ -5,18 +5,18 @@ fun bar(): String? = null
fun foo() {
var x = ArrayList<String>()
x.add(null)
x.add(bar())
x.add(<!NULL_FOR_NONNULL_TYPE!>null<!>)
x.add(<!ARGUMENT_TYPE_MISMATCH!>bar()<!>)
x.add("")
x[0] = null
x[0] = bar()
x[0] = <!NULL_FOR_NONNULL_TYPE!>null<!>
x[0] = <!ARGUMENT_TYPE_MISMATCH!>bar()<!>
x[0] = ""
val b1: MutableList<String?> = x
val b1: MutableList<String?> = <!INITIALIZER_TYPE_MISMATCH!>x<!>
val b2: MutableList<String> = x
val b3: List<String?> = x
val b4: Collection<String?> = x
val b6: MutableCollection<String?> = x
}
val b6: MutableCollection<String?> = <!INITIALIZER_TYPE_MISMATCH!>x<!>
}
@@ -14,7 +14,7 @@ fun foo() {
x[0] = ""
val b1: MutableList<String?> = x
val b2: MutableList<String> = x
val b2: MutableList<String> = <!INITIALIZER_TYPE_MISMATCH!>x<!>
val b3: List<String?> = x
val b4: Collection<String?> = x
@@ -28,5 +28,5 @@ fun foo() {
x.add("")
val b1: Collection<String?> = x
val b2: MutableCollection<String?> = x
val b2: MutableCollection<String?> = <!INITIALIZER_TYPE_MISMATCH!>x<!>
}
@@ -31,10 +31,10 @@ fun foo() {
x[0] = bar()
x[0] = ""
val b1: MutableList<String?> = x
val b1: MutableList<String?> = <!INITIALIZER_TYPE_MISMATCH!>x<!>
val b2: MutableList<String> = x
val b3: List<String?> = x
val b4: Collection<String?> = x
val b6: MutableCollection<String?> = x
val b6: MutableCollection<String?> = <!INITIALIZER_TYPE_MISMATCH!>x<!>
}
@@ -7,30 +7,30 @@ fun bar(): String? = null
fun fooHashSet() {
var x = HashSet<String>()
x.add(null)
x.add(bar())
x.add(<!NULL_FOR_NONNULL_TYPE!>null<!>)
x.add(<!ARGUMENT_TYPE_MISMATCH!>bar()<!>)
x.add("")
val b1: MutableSet<String?> = x
val b1: MutableSet<String?> = <!INITIALIZER_TYPE_MISMATCH!>x<!>
val b2: MutableSet<String> = x
val b3: Set<String?> = x
val b4: Collection<String?> = x
val b6: MutableCollection<String?> = x
val b6: MutableCollection<String?> = <!INITIALIZER_TYPE_MISMATCH!>x<!>
}
fun fooTreeSet() {
var x = TreeSet<String>()
x.add(null)
x.add(bar())
x.add(<!NULL_FOR_NONNULL_TYPE!>null<!>)
x.add(<!ARGUMENT_TYPE_MISMATCH!>bar()<!>)
x.add("")
val b1: MutableSet<String?> = x
val b1: MutableSet<String?> = <!INITIALIZER_TYPE_MISMATCH!>x<!>
val b2: MutableSet<String> = x
val b3: Set<String?> = x
val b4: Collection<String?> = x
val b6: MutableCollection<String?> = x
val b6: MutableCollection<String?> = <!INITIALIZER_TYPE_MISMATCH!>x<!>
}
fun fooLinkedHashSet() {
@@ -39,10 +39,10 @@ fun fooLinkedHashSet() {
x.add(bar())
x.add("")
val b1: MutableSet<String?> = x
val b1: MutableSet<String?> = <!INITIALIZER_TYPE_MISMATCH!>x<!>
val b2: MutableSet<String> = x
val b3: Set<String?> = x
val b4: Collection<String?> = x
val b6: MutableCollection<String?> = x
val b6: MutableCollection<String?> = <!INITIALIZER_TYPE_MISMATCH!>x<!>
}
@@ -34,11 +34,11 @@ FILE fqName:<root> fileName:/AbstractMutableMap.kt
overridden:
public open fun clear (): kotlin.Unit [fake_override] declared in kotlin.collections.AbstractMutableMap
$this: VALUE_PARAMETER name:<this> type:java.util.AbstractMap<K of java.util.AbstractMap, V of java.util.AbstractMap>
FUN FAKE_OVERRIDE name:putAll visibility:public modality:OPEN <> ($this:java.util.AbstractMap<K of java.util.AbstractMap, V of java.util.AbstractMap>, p0:@[EnhancedNullability] kotlin.collections.Map<out @[FlexibleNullability] K of <root>.MyMap?, out @[FlexibleNullability] V of <root>.MyMap?>) returnType:kotlin.Unit [fake_override]
FUN FAKE_OVERRIDE name:putAll visibility:public modality:OPEN <> ($this:java.util.AbstractMap<K of java.util.AbstractMap, V of java.util.AbstractMap>, p0:@[EnhancedNullability] kotlin.collections.Map<out @[FlexibleNullability] K of <root>.MyMap?, @[FlexibleNullability] V of <root>.MyMap?>) returnType:kotlin.Unit [fake_override]
overridden:
public open fun putAll (p0: @[EnhancedNullability] kotlin.collections.Map<out @[FlexibleNullability] K of kotlin.collections.AbstractMutableMap?, out @[FlexibleNullability] V of kotlin.collections.AbstractMutableMap?>): kotlin.Unit [fake_override] declared in kotlin.collections.AbstractMutableMap
$this: VALUE_PARAMETER name:<this> type:java.util.AbstractMap<K of java.util.AbstractMap, V of java.util.AbstractMap>
VALUE_PARAMETER name:p0 index:0 type:@[EnhancedNullability] kotlin.collections.Map<out @[FlexibleNullability] K of <root>.MyMap?, out @[FlexibleNullability] V of <root>.MyMap?>
VALUE_PARAMETER name:p0 index:0 type:@[EnhancedNullability] kotlin.collections.Map<out @[FlexibleNullability] K of <root>.MyMap?, @[FlexibleNullability] V of <root>.MyMap?>
FUN FAKE_OVERRIDE name:remove visibility:public modality:OPEN <> ($this:java.util.AbstractMap<K of java.util.AbstractMap, V of java.util.AbstractMap>, p0:@[FlexibleNullability] K of <root>.MyMap?) returnType:V of <root>.MyMap? [fake_override]
overridden:
public open fun remove (p0: @[FlexibleNullability] K of kotlin.collections.AbstractMutableMap?): V of kotlin.collections.AbstractMutableMap? [fake_override] declared in kotlin.collections.AbstractMutableMap
@@ -74,12 +74,12 @@ FILE fqName:<root> fileName:/AbstractMutableMap.kt
public open fun replaceAll (p0: @[EnhancedNullability] java.util.function.BiFunction<in @[EnhancedNullability] K of kotlin.collections.AbstractMutableMap, in @[EnhancedNullability] V of kotlin.collections.AbstractMutableMap, out @[EnhancedNullability] V of kotlin.collections.AbstractMutableMap>): kotlin.Unit [fake_override] declared in kotlin.collections.AbstractMutableMap
$this: VALUE_PARAMETER name:<this> type:kotlin.collections.MutableMap<K of kotlin.collections.MutableMap, V of kotlin.collections.MutableMap>
VALUE_PARAMETER name:p0 index:0 type:@[EnhancedNullability] java.util.function.BiFunction<in @[EnhancedNullability] K of <root>.MyMap, in @[EnhancedNullability] V of <root>.MyMap, out @[EnhancedNullability] V of <root>.MyMap>
FUN FAKE_OVERRIDE name:merge visibility:public modality:OPEN <> ($this:kotlin.collections.MutableMap<K of kotlin.collections.MutableMap, V of kotlin.collections.MutableMap>, p0:@[EnhancedNullability] K of <root>.MyMap, p1:@[EnhancedNullability] V of <root>.MyMap, p2:@[EnhancedNullability] java.util.function.BiFunction<in @[EnhancedNullability] V of <root>.MyMap, in @[EnhancedNullability] V of <root>.MyMap, out V of <root>.MyMap?>) returnType:V of <root>.MyMap? [fake_override]
FUN FAKE_OVERRIDE name:merge visibility:public modality:OPEN <> ($this:kotlin.collections.MutableMap<K of kotlin.collections.MutableMap, V of kotlin.collections.MutableMap>, p0:@[EnhancedNullability] K of <root>.MyMap, p1:@[EnhancedNullability] {V of <root>.MyMap & Any}, p2:@[EnhancedNullability] java.util.function.BiFunction<in @[EnhancedNullability] V of <root>.MyMap, in @[EnhancedNullability] V of <root>.MyMap, out V of <root>.MyMap?>) returnType:V of <root>.MyMap? [fake_override]
overridden:
public open fun merge (p0: @[EnhancedNullability] K of kotlin.collections.AbstractMutableMap, p1: @[EnhancedNullability] {V of kotlin.collections.AbstractMutableMap & Any}, p2: @[EnhancedNullability] java.util.function.BiFunction<in @[EnhancedNullability] {V of kotlin.collections.AbstractMutableMap & Any}, in @[EnhancedNullability] {V of kotlin.collections.AbstractMutableMap & Any}, out V of kotlin.collections.AbstractMutableMap?>): V of kotlin.collections.AbstractMutableMap? [fake_override] declared in kotlin.collections.AbstractMutableMap
$this: VALUE_PARAMETER name:<this> type:kotlin.collections.MutableMap<K of kotlin.collections.MutableMap, V of kotlin.collections.MutableMap>
VALUE_PARAMETER name:p0 index:0 type:@[EnhancedNullability] K of <root>.MyMap
VALUE_PARAMETER name:p1 index:1 type:@[EnhancedNullability] V of <root>.MyMap
VALUE_PARAMETER name:p1 index:1 type:@[EnhancedNullability] {V of <root>.MyMap & Any}
VALUE_PARAMETER name:p2 index:2 type:@[EnhancedNullability] java.util.function.BiFunction<in @[EnhancedNullability] V of <root>.MyMap, in @[EnhancedNullability] V of <root>.MyMap, out V of <root>.MyMap?>
FUN FAKE_OVERRIDE name:computeIfPresent visibility:public modality:OPEN <> ($this:kotlin.collections.MutableMap<K of kotlin.collections.MutableMap, V of kotlin.collections.MutableMap>, p0:@[EnhancedNullability] K of <root>.MyMap, p1:@[EnhancedNullability] java.util.function.BiFunction<in @[EnhancedNullability] K of <root>.MyMap, in @[EnhancedNullability] V of <root>.MyMap, out V of <root>.MyMap?>) returnType:V of <root>.MyMap? [fake_override]
overridden: