[NI] Improve CST algorithm to handle non-fixed variables
#KT-32456 Fixed #KT-32423 Fixed #KT-32818 Fixed #KT-33197 Fixed
This commit is contained in:
Vendored
+90
@@ -0,0 +1,90 @@
|
||||
// !LANGUAGE: +NewInference
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_EXPRESSION
|
||||
|
||||
fun <T> select(x: T, y: T): T = x
|
||||
open class Inv<K>
|
||||
class SubInv<V> : Inv<V>()
|
||||
|
||||
fun testSimple() {
|
||||
val a0 = select(Inv<Int>(), SubInv())
|
||||
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Inv<kotlin.Int>")!>a0<!>
|
||||
|
||||
val a1 = select(SubInv<Int>(), Inv())
|
||||
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Inv<kotlin.Int>")!>a1<!>
|
||||
}
|
||||
|
||||
fun testNullability() {
|
||||
val n1 = select(Inv<Int?>(), SubInv())
|
||||
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Inv<kotlin.Int?>")!>n1<!>
|
||||
|
||||
val n2 = select(SubInv<Int?>(), Inv())
|
||||
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Inv<kotlin.Int?>")!>n2<!>
|
||||
}
|
||||
|
||||
fun testNested() {
|
||||
val n1 = select(Inv<Inv<Int>>(), SubInv())
|
||||
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Inv<Inv<kotlin.Int>>")!>n1<!>
|
||||
|
||||
val n2 = select(SubInv<SubInv<Int>>(), Inv())
|
||||
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Inv<SubInv<kotlin.Int>>")!>n2<!>
|
||||
|
||||
fun <K> createInvInv(): Inv<Inv<K>> = TODO()
|
||||
|
||||
val n3 = select(SubInv<SubInv<Int>>(), createInvInv())
|
||||
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Inv<out Inv<kotlin.Int>>")!>n3<!>
|
||||
}
|
||||
|
||||
fun testCaptured(cSub: SubInv<out Number>, cInv: Inv<out Number>) {
|
||||
val c1 = select(cInv, SubInv())
|
||||
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Inv<out kotlin.Number>")!>c1<!>
|
||||
|
||||
val c2 = select(cSub, Inv())
|
||||
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Inv<out kotlin.Number>")!>c2<!>
|
||||
}
|
||||
|
||||
fun testVariableWithBound() {
|
||||
fun <K : Number> createWithNumberBound(): Inv<K> = TODO()
|
||||
fun <K : <!FINAL_UPPER_BOUND!>Int<!>> createWithIntBound(): Inv<K> = TODO()
|
||||
|
||||
val c1 = select(SubInv<Int>(), createWithNumberBound())
|
||||
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Inv<kotlin.Int>")!>c1<!>
|
||||
|
||||
// should be an error after variable fixation
|
||||
val c2 = select(SubInv<String>(), createWithNumberBound())
|
||||
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Inv<kotlin.String>")!>c2<!>
|
||||
|
||||
// should be an error after variable fixation
|
||||
val c3 = select(SubInv<Double>(), createWithIntBound())
|
||||
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Inv<kotlin.Double>")!>c3<!>
|
||||
}
|
||||
|
||||
fun testCapturedVariable() {
|
||||
fun <K> createInvOut(): Inv<out K> = TODO()
|
||||
fun <V> createSubInvOut(): SubInv<out V> = TODO()
|
||||
|
||||
fun <K> createInvIn(): Inv<in K> = TODO()
|
||||
|
||||
val c1 = select(SubInv<Number>(), createInvOut())
|
||||
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Inv<kotlin.Number>")!>c1<!>
|
||||
|
||||
val c2 = select(createSubInvOut<Number>(), createInvOut())
|
||||
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Inv<out kotlin.Number>")!>c2<!>
|
||||
|
||||
val c3 = select(SubInv<Number>(), createInvIn())
|
||||
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("Inv<out kotlin.Number>")!>c3<!>
|
||||
}
|
||||
compiler/testData/diagnostics/tests/inference/commonSystem/cstWithTypeContainingNonFixedVariable.txt
Vendored
+23
@@ -0,0 +1,23 @@
|
||||
package
|
||||
|
||||
public fun </*0*/ T> select(/*0*/ x: T, /*1*/ y: T): T
|
||||
public fun testCaptured(/*0*/ cSub: SubInv<out kotlin.Number>, /*1*/ cInv: Inv<out kotlin.Number>): kotlin.Unit
|
||||
public fun testCapturedVariable(): kotlin.Unit
|
||||
public fun testNested(): kotlin.Unit
|
||||
public fun testNullability(): kotlin.Unit
|
||||
public fun testSimple(): kotlin.Unit
|
||||
public fun testVariableWithBound(): kotlin.Unit
|
||||
|
||||
public open class Inv</*0*/ K> {
|
||||
public constructor Inv</*0*/ K>()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public final class SubInv</*0*/ V> : Inv<V> {
|
||||
public constructor SubInv</*0*/ V>()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
// !WITH_NEW_INFERENCE
|
||||
|
||||
fun <T : Any> nullable(): T? = null
|
||||
|
||||
val value = nullable<Int>() ?: <!OI;TYPE_INFERENCE_EXPECTED_TYPE_MISMATCH!>nullable()<!>
|
||||
@@ -0,0 +1,4 @@
|
||||
package
|
||||
|
||||
public val value: kotlin.Int
|
||||
public fun </*0*/ T : kotlin.Any> nullable(): T?
|
||||
@@ -0,0 +1,19 @@
|
||||
// !LANGUAGE: +NewInference
|
||||
// !DIAGNOSTICS: -UNUSED_EXPRESSION
|
||||
|
||||
fun test(condition: Boolean) {
|
||||
val list1 =
|
||||
if (condition) mutableListOf<Int>()
|
||||
else emptyList()
|
||||
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.collections.List<kotlin.Int>")!>list1<!>
|
||||
|
||||
val list2 =
|
||||
if (condition) mutableListOf()
|
||||
else emptyList<Int>()
|
||||
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.collections.List<kotlin.Int>")!>list2<!>
|
||||
}
|
||||
|
||||
fun <T> mutableListOf(): MutableList<T> = TODO()
|
||||
fun <T> emptyList(): List<T> = TODO()
|
||||
@@ -0,0 +1,5 @@
|
||||
package
|
||||
|
||||
public fun </*0*/ T> emptyList(): kotlin.collections.List<T>
|
||||
public fun </*0*/ T> mutableListOf(): kotlin.collections.MutableList<T>
|
||||
public fun test(/*0*/ condition: kotlin.Boolean): kotlin.Unit
|
||||
Vendored
+30
@@ -0,0 +1,30 @@
|
||||
// !LANGUAGE: +NewInference
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER -UNUSED_EXPRESSION
|
||||
|
||||
// FILE: Inv2.java
|
||||
|
||||
public class Inv2<K, V> {}
|
||||
|
||||
// FILE: JavaSet.java
|
||||
|
||||
public class JavaSet {
|
||||
public static <E> java.util.Set<E> newIdentityHashSet() { return null; }
|
||||
|
||||
public static <K, V> V get(Inv2<K, V> slice, K key) { return null; }
|
||||
}
|
||||
|
||||
// FILE: test.kt
|
||||
|
||||
fun <K> select(x: K, y: K): K = x
|
||||
|
||||
fun <K, T> addElementToSlice(
|
||||
slice: Inv2<K, MutableCollection<T>>,
|
||||
key: K,
|
||||
element: T
|
||||
) {
|
||||
val a = select(JavaSet.get(slice, key), JavaSet.newIdentityHashSet())
|
||||
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("(kotlin.collections.MutableCollection<T>..kotlin.collections.Collection<T>?)")!>a<!>
|
||||
|
||||
a.add(element)
|
||||
}
|
||||
Vendored
+22
@@ -0,0 +1,22 @@
|
||||
package
|
||||
|
||||
public fun </*0*/ K, /*1*/ T> addElementToSlice(/*0*/ slice: Inv2<K, kotlin.collections.MutableCollection<T>>, /*1*/ key: K, /*2*/ element: T): kotlin.Unit
|
||||
public fun </*0*/ K> select(/*0*/ x: K, /*1*/ y: K): K
|
||||
|
||||
public open class Inv2</*0*/ K : kotlin.Any!, /*1*/ V : kotlin.Any!> {
|
||||
public constructor Inv2</*0*/ K : kotlin.Any!, /*1*/ V : kotlin.Any!>()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public open class JavaSet {
|
||||
public constructor JavaSet()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
|
||||
// Static members
|
||||
public open fun </*0*/ K : kotlin.Any!, /*1*/ V : kotlin.Any!> get(/*0*/ slice: Inv2<K!, V!>!, /*1*/ key: K!): V!
|
||||
public open fun </*0*/ E : kotlin.Any!> newIdentityHashSet(): kotlin.collections.(Mutable)Set<E!>!
|
||||
}
|
||||
Vendored
+12
@@ -0,0 +1,12 @@
|
||||
// !LANGUAGE: +NewInference
|
||||
// !DIAGNOSTICS: -UNUSED_VARIABLE -UNUSED_PARAMETER
|
||||
|
||||
class Inv<T>
|
||||
|
||||
fun <K> select(x: K, y: K): K = x
|
||||
|
||||
fun <V> outToOut(x: Inv<out V>): Inv<out V> = TODO()
|
||||
|
||||
fun test(invOutAny: Inv<out Any>, invAny: Inv<Any>) {
|
||||
val a: Inv<out Any> = select(invAny, outToOut(invOutAny))
|
||||
}
|
||||
Vendored
+12
@@ -0,0 +1,12 @@
|
||||
package
|
||||
|
||||
public fun </*0*/ V> outToOut(/*0*/ x: Inv<out V>): Inv<out V>
|
||||
public fun </*0*/ K> select(/*0*/ x: K, /*1*/ y: K): K
|
||||
public fun test(/*0*/ invOutAny: Inv<out kotlin.Any>, /*1*/ invAny: Inv<kotlin.Any>): kotlin.Unit
|
||||
|
||||
public final class Inv</*0*/ T> {
|
||||
public constructor Inv</*0*/ T>()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
+2
-2
@@ -11,13 +11,13 @@ fun <K> elvisExact(x: K?, y: K): @kotlin.internal.Exact K = y
|
||||
fun <T : Number> materialize(): T? = null
|
||||
|
||||
fun test(nullableSample: ISample, any: Any) {
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("ISample")!>elvisSimple(
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("ISample?")!>elvisSimple(
|
||||
nullableSample,
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("{ISample & Number}?")!>materialize()<!>
|
||||
)<!>
|
||||
|
||||
elvisSimple(
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("ISample")!>elvisSimple(nullableSample, materialize())<!>,
|
||||
<!DEBUG_INFO_EXPRESSION_TYPE("ISample?")!>elvisSimple(nullableSample, materialize())<!>,
|
||||
any
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user