[FIR] Refactor upper bound validation with better source element info

Attach source information to each argument of the type before expanding
to preserve information during validation. This allows errors to be
reported on the original argument during nested type alias expansion.

^KT-50798 Fixed
^KT-50703 Fixed
This commit is contained in:
Brian Norman
2023-05-19 13:46:47 -05:00
committed by Space Team
parent d82a6f2fa2
commit b2230327df
13 changed files with 163 additions and 93 deletions
@@ -9,19 +9,19 @@ typealias OneList<X> = List<TK<X, X>>
typealias Both<T, K> = TK<T, K>
typealias BothList<T, K> = List<TK<T, K>>
object O1 : <!UPPER_BOUND_VIOLATED_IN_TYPEALIAS_EXPANSION!>One<Any><!>() // compiler error expected
object O2 : <!UPPER_BOUND_VIOLATED_IN_TYPEALIAS_EXPANSION!>Both<Any, Any><!>()
object O1 : One<<!UPPER_BOUND_VIOLATED, UPPER_BOUND_VIOLATED!>Any<!>>() // compiler error expected
object O2 : Both<<!UPPER_BOUND_VIOLATED!>Any<!>, <!UPPER_BOUND_VIOLATED!>Any<!>>()
class A1<T : <!UPPER_BOUND_VIOLATED_IN_TYPEALIAS_EXPANSION!>One<Any><!>>
class A2<T : <!UPPER_BOUND_VIOLATED_IN_TYPEALIAS_EXPANSION!>One<Any, Any><!>>
class A1<T : One<<!UPPER_BOUND_VIOLATED, UPPER_BOUND_VIOLATED!>Any<!>>>
class A2<T : One<<!UPPER_BOUND_VIOLATED, UPPER_BOUND_VIOLATED!>Any<!>, Any>>
interface IO1 : OneList<Any> {}
interface IO2 : BothList<Any, Any> {}
interface IO1 : OneList<<!UPPER_BOUND_VIOLATED, UPPER_BOUND_VIOLATED!>Any<!>> {}
interface IO2 : BothList<<!UPPER_BOUND_VIOLATED!>Any<!>, <!UPPER_BOUND_VIOLATED!>Any<!>> {}
fun foo1(x: <!UPPER_BOUND_VIOLATED_IN_TYPEALIAS_EXPANSION!>One<Any><!>) {}
fun foo2(x: <!UPPER_BOUND_VIOLATED_IN_TYPEALIAS_EXPANSION!>Both<Any, Any><!>) {}
fun foo1(x: One<<!UPPER_BOUND_VIOLATED, UPPER_BOUND_VIOLATED!>Any<!>>) {}
fun foo2(x: Both<<!UPPER_BOUND_VIOLATED!>Any<!>, <!UPPER_BOUND_VIOLATED!>Any<!>>) {}
fun main() {
<!UPPER_BOUND_VIOLATED, UPPER_BOUND_VIOLATED!>One<Any>()<!>
<!UPPER_BOUND_VIOLATED, UPPER_BOUND_VIOLATED!>Both<Any, Any>()<!>
One<<!UPPER_BOUND_VIOLATED, UPPER_BOUND_VIOLATED!>Any<!>>()
Both<<!UPPER_BOUND_VIOLATED!>Any<!>, <!UPPER_BOUND_VIOLATED!>Any<!>>()
}
@@ -9,19 +9,19 @@ typealias OneList<X> = List<TK<X, X>>
typealias Both<T, K> = TK<T, K>
typealias BothList<T, K> = List<TK<T, K>>
object O1 : <!UPPER_BOUND_VIOLATED_IN_TYPEALIAS_EXPANSION!>One<Any><!>() // compiler error expected
object O2 : <!UPPER_BOUND_VIOLATED_IN_TYPEALIAS_EXPANSION!>Both<Any, Any><!>()
object O1 : One<<!UPPER_BOUND_VIOLATED, UPPER_BOUND_VIOLATED!>Any<!>>() // compiler error expected
object O2 : Both<<!UPPER_BOUND_VIOLATED!>Any<!>, <!UPPER_BOUND_VIOLATED!>Any<!>>()
class A1<T : <!UPPER_BOUND_VIOLATED_IN_TYPEALIAS_EXPANSION!>One<Any><!>>
class A2<T : <!UPPER_BOUND_VIOLATED_IN_TYPEALIAS_EXPANSION!>One<Any, Any><!>>
class A1<T : One<<!UPPER_BOUND_VIOLATED, UPPER_BOUND_VIOLATED!>Any<!>>>
class A2<T : One<<!UPPER_BOUND_VIOLATED, UPPER_BOUND_VIOLATED!>Any<!>, Any>>
interface IO1 : OneList<Any> {}
interface IO2 : BothList<Any, Any> {}
interface IO1 : OneList<<!UPPER_BOUND_VIOLATED, UPPER_BOUND_VIOLATED!>Any<!>> {}
interface IO2 : BothList<<!UPPER_BOUND_VIOLATED!>Any<!>, <!UPPER_BOUND_VIOLATED!>Any<!>> {}
fun foo1(x: <!UPPER_BOUND_VIOLATED_IN_TYPEALIAS_EXPANSION!>One<Any><!>) {}
fun foo2(x: <!UPPER_BOUND_VIOLATED_IN_TYPEALIAS_EXPANSION!>Both<Any, Any><!>) {}
fun foo1(x: One<<!UPPER_BOUND_VIOLATED, UPPER_BOUND_VIOLATED!>Any<!>>) {}
fun foo2(x: Both<<!UPPER_BOUND_VIOLATED!>Any<!>, <!UPPER_BOUND_VIOLATED!>Any<!>>) {}
fun main() {
<!UPPER_BOUND_VIOLATED, UPPER_BOUND_VIOLATED!>One<Any>()<!>
<!UPPER_BOUND_VIOLATED, UPPER_BOUND_VIOLATED!>Both<Any, Any>()<!>
One<<!UPPER_BOUND_VIOLATED, UPPER_BOUND_VIOLATED!>Any<!>>()
Both<<!UPPER_BOUND_VIOLATED!>Any<!>, <!UPPER_BOUND_VIOLATED!>Any<!>>()
}
@@ -4,8 +4,8 @@ typealias N<T> = Num<T>
typealias N2<T> = N<T>
val x1 = Num<<!UPPER_BOUND_VIOLATED!>String<!>>(<!ARGUMENT_TYPE_MISMATCH!>""<!>)
val x2 = <!UPPER_BOUND_VIOLATED!>N<String>(<!ARGUMENT_TYPE_MISMATCH!>""<!>)<!>
val x3 = <!UPPER_BOUND_VIOLATED!>N2<String>(<!ARGUMENT_TYPE_MISMATCH!>""<!>)<!>
val x2 = N<<!UPPER_BOUND_VIOLATED!>String<!>>(<!ARGUMENT_TYPE_MISMATCH!>""<!>)
val x3 = N2<<!UPPER_BOUND_VIOLATED!>String<!>>(<!ARGUMENT_TYPE_MISMATCH!>""<!>)
class TColl<T, C : Collection<T>>
@@ -13,5 +13,5 @@ typealias TC<T, C> = TColl<T, C>
typealias TC2<T, C> = TC<T, C>
val y1 = TColl<Any, <!UPPER_BOUND_VIOLATED!>Any<!>>()
val y2 = <!UPPER_BOUND_VIOLATED!>TC<Any, Any>()<!>
val y3 = <!UPPER_BOUND_VIOLATED!>TC2<Any, Any>()<!>
val y2 = TC<Any, <!UPPER_BOUND_VIOLATED!>Any<!>>()
val y3 = TC2<Any, <!UPPER_BOUND_VIOLATED!>Any<!>>()
@@ -8,9 +8,9 @@ typealias TC2<T1, T2> = TC<T1, T2>
fun test1(x: TC2<Number, Collection<Number>>) {}
fun test2(x: TC2<Number, Collection<Int>>) {}
fun test3(x: TC2<Number, List<Int>>) {}
fun test4(x: <!UPPER_BOUND_VIOLATED_IN_TYPEALIAS_EXPANSION!>TC2<Number, List<Any>><!>) {}
fun test4(x: TC2<Number, <!UPPER_BOUND_VIOLATED!>List<Any><!>>) {}
val test5 = TC2<Number, Collection<Number>>()
val test6 = TC2<Number, Collection<Int>>()
val test7 = TC2<Number, List<Int>>()
val test8 = <!UPPER_BOUND_VIOLATED!>TC2<Number, List<Any>>()<!>
val test8 = TC2<Number, <!UPPER_BOUND_VIOLATED!>List<Any><!>>()
@@ -10,12 +10,12 @@ typealias MMMM<A3> = NL<A3>
typealias TC<T1, T2> = TColl<T1, T2>
fun test1(x: NA<Int>) {}
fun test2(x: <!UPPER_BOUND_VIOLATED_IN_TYPEALIAS_EXPANSION!>NA<Any><!>) {}
fun test2(x: NA<<!UPPER_BOUND_VIOLATED!>Any<!>>) {}
fun test3(x: NL<Int>) {}
fun test4(x: <!UPPER_BOUND_VIOLATED_IN_TYPEALIAS_EXPANSION!>NL<Any><!>) {}
val test5 = NA<Int>()
val test6 = <!UPPER_BOUND_VIOLATED!>NA<Any>()<!>
val test6 = NA<<!UPPER_BOUND_VIOLATED!>Any<!>>()
val test7 = NL<Int>()
val test8 = MMMM<Int>()
val test9dwd = <!UPPER_BOUND_VIOLATED!>NL<Any>()<!>
@@ -23,9 +23,9 @@ val test9dwd = <!UPPER_BOUND_VIOLATED!>NL<Any>()<!>
fun test9(x: TC<Number, Collection<Number>>) {}
fun test10(x: TC<Number, Collection<Int>>) {}
fun test11(x: TC<Number, List<Int>>) {}
fun test12(x: <!UPPER_BOUND_VIOLATED_IN_TYPEALIAS_EXPANSION!>TC<Number, List<Any>><!>) {}
fun test12(x: TC<Number, <!UPPER_BOUND_VIOLATED!>List<Any><!>>) {}
val test13 = TC<Number, Collection<Number>>()
val test14 = TC<Number, Collection<Int>>()
val test15 = TC<Number, List<Int>>()
val test16 = <!UPPER_BOUND_VIOLATED!>TC<Number, List<Any>>()<!>
val test16 = TC<Number, <!UPPER_BOUND_VIOLATED!>List<Any><!>>()
@@ -5,16 +5,16 @@ class TC<T, C : Collection<T>>
typealias TCAlias<T, C> = TC<T, C>
typealias TCAliasT<T> = TC<T, <!UPPER_BOUND_VIOLATED!>Any<!>>
typealias TCAliasC<C> = TC<Any, C>
typealias TCAliasT1<T> = <!UPPER_BOUND_VIOLATED_IN_TYPEALIAS_EXPANSION!>TCAlias<T, Any><!>
typealias TCAliasT1<T> = TCAlias<T, <!UPPER_BOUND_VIOLATED!>Any<!>>
typealias TCAliasC1<C> = TCAlias<Any, C>
typealias Test1 = TC<Any, <!UPPER_BOUND_VIOLATED!>Any<!>>
typealias Test2 = TC<Any, Collection<Any>>
typealias Test3 = <!UPPER_BOUND_VIOLATED_IN_TYPEALIAS_EXPANSION!>TCAlias<Any, Any><!>
typealias Test3 = TCAlias<Any, <!UPPER_BOUND_VIOLATED!>Any<!>>
typealias Test4 = TCAlias<Any, Collection<Any>>
typealias Test5 = <!UPPER_BOUND_VIOLATED_IN_TYPEALIAS_EXPANSION!>TCAliasT<Any><!>
typealias Test6 = <!UPPER_BOUND_VIOLATED_IN_TYPEALIAS_EXPANSION!>TCAliasC<Any><!>
typealias Test6 = TCAliasC<<!UPPER_BOUND_VIOLATED!>Any<!>>
typealias Test7 = TCAliasC<Collection<Any>>
typealias Test8 = <!UPPER_BOUND_VIOLATED_IN_TYPEALIAS_EXPANSION!>TCAliasT1<Any><!>
typealias Test9 = <!UPPER_BOUND_VIOLATED_IN_TYPEALIAS_EXPANSION!>TCAliasC1<Any><!>
typealias Test9 = TCAliasC1<<!UPPER_BOUND_VIOLATED!>Any<!>>
typealias Test10 = TCAliasC1<Collection<Any>>
@@ -0,0 +1,11 @@
interface Order<T>
typealias Ord<T> = Order<T>
class Test1<T1 : Ord<T1>>
interface Num<T : Number>
typealias N<T> = Num<T>
class Test2<T : N<<!UPPER_BOUND_VIOLATED!>String<!>>>
@@ -1,4 +1,3 @@
// FIR_IDENTICAL
interface Order<T>
typealias Ord<T> = Order<T>
@@ -30,7 +30,7 @@ typealias N<T> = Num<T>
val testN0 = N(<!ARGUMENT_TYPE_MISMATCH!>""<!>)
val testN1 = N<Int>(1)
val testN1a = <!UPPER_BOUND_VIOLATED!>N<String>(<!ARGUMENT_TYPE_MISMATCH!>""<!>)<!>
val testN1a = N<<!UPPER_BOUND_VIOLATED!>String<!>>(<!ARGUMENT_TYPE_MISMATCH!>""<!>)
val testN2 = <!INAPPLICABLE_CANDIDATE!>N<!><Int, Int>(1)
class MyPair<T1 : CharSequence, T2 : Number>(val string: T1, val number: T2)
@@ -38,4 +38,4 @@ typealias MP<T1> = MyPair<String, T1>
val testMP0 = MP<Int>("", 1)
val testMP1 = MP(<!ARGUMENT_TYPE_MISMATCH!>1<!>, <!ARGUMENT_TYPE_MISMATCH!>""<!>)
val testMP2 = <!UPPER_BOUND_VIOLATED!>MP<String>(<!ARGUMENT_TYPE_MISMATCH!>""<!>, <!ARGUMENT_TYPE_MISMATCH!>""<!>)<!>
val testMP2 = MP<<!UPPER_BOUND_VIOLATED!>String<!>>(<!ARGUMENT_TYPE_MISMATCH!>""<!>, <!ARGUMENT_TYPE_MISMATCH!>""<!>)
@@ -27,11 +27,11 @@ typealias A<A> = MapLike<A, Int>
typealias A2<B> = Foo<MapLike<B, Int>>
typealias A3<C> = ListLike<List<C>>
fun main1(x: <!UPPER_BOUND_VIOLATED_IN_TYPEALIAS_EXPANSION!>A<Int?><!>) {}
fun main2(x: A2<Int?>) {}
fun main1(x: A<<!UPPER_BOUND_VIOLATED!>Int?<!>>) {}
fun main2(x: A2<<!UPPER_BOUND_VIOLATED!>Int?<!>>) {}
fun main3(x: <!UPPER_BOUND_VIOLATED_IN_TYPEALIAS_EXPANSION!>A3<Int?><!>) {}
fun main3() {
val x = <!UPPER_BOUND_VIOLATED!>A3<Int?>()<!> // TODO: support reporting errors on typealias constructor calls
val x2 = <!UPPER_BOUND_VIOLATED!>A<Int?>()<!> // TODO: support reporting errors on typealias constructor calls
val x2 = A<<!UPPER_BOUND_VIOLATED!>Int?<!>>() // TODO: support reporting errors on typealias constructor calls
val y: <!UPPER_BOUND_VIOLATED_IN_TYPEALIAS_EXPANSION!>A3<Int?><!> = <!UPPER_BOUND_VIOLATED!>A3<Int?>()<!>
}
@@ -27,11 +27,11 @@ typealias A<A> = MapLike<A, Int>
typealias A2<B> = Foo<MapLike<B, Int>>
typealias A3<C> = ListLike<List<C>>
fun main1(x: <!UPPER_BOUND_VIOLATED_IN_TYPEALIAS_EXPANSION!>A<Int?><!>) {}
fun main2(x: A2<Int?>) {}
fun main1(x: A<<!UPPER_BOUND_VIOLATED!>Int?<!>>) {}
fun main2(x: A2<<!UPPER_BOUND_VIOLATED!>Int?<!>>) {}
fun main3(x: <!UPPER_BOUND_VIOLATED_IN_TYPEALIAS_EXPANSION!>A3<Int?><!>) {}
fun main3() {
val x = <!UPPER_BOUND_VIOLATED!>A3<Int?>()<!>
val x2 = <!UPPER_BOUND_VIOLATED!>A<Int?>()<!>
val x2 = A<<!UPPER_BOUND_VIOLATED!>Int?<!>>()
val y: <!UPPER_BOUND_VIOLATED_IN_TYPEALIAS_EXPANSION!>A3<Int?><!> = <!UPPER_BOUND_VIOLATED!>A3<Int?>()<!>
}