K2: Fix PCLA breaking change when using a bare type on a type variable

See the change at docs/fir/pcla.md and the kdoc
at `getAndSemiFixCurrentResultIfTypeVariable` for clarification

^KT-64840 Fixed
This commit is contained in:
Denis.Zharkov
2024-03-08 19:38:58 +01:00
committed by Space Team
parent 141be17b4b
commit 232c3aeadc
10 changed files with 78 additions and 33 deletions
@@ -1,20 +0,0 @@
// ISSUE: KT-64840 (K2/PCLA difference)
class Controller<T> {
fun yield(t: T): Boolean = true
}
fun <S> generate(g: suspend Controller<S>.() -> Unit): S = TODO()
interface A<F> {
val a: F?
}
interface B<G> : A<G>
fun <X> predicate(x: X, c: Controller<in X>, p: (X) -> Boolean) {}
fun main(a: A<*>) {
generate {
predicate(a, this) { it is <!NO_TYPE_ARGUMENTS_ON_RHS!>B<!> }
}.a
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// ISSUE: KT-64840 (K2/PCLA difference)
class Controller<T> {
fun yield(t: T): Boolean = true
@@ -18,8 +18,8 @@ fun <X> withCallback(x: X, c: Controller<in X>, p: (X) -> Unit) {}
fun main(a: A<String>) {
val x = generate {
withCallback(a, this) {
(it as <!NO_TYPE_ARGUMENTS_ON_RHS!>B<!>).<!UNRESOLVED_REFERENCE!>b<!>.length
it.<!UNRESOLVED_REFERENCE!>b<!>.length
(it as B).b.length
it.b.length
it.a.length
}
}
@@ -15,6 +15,8 @@ interface C : CommonSupertype
fun <X> predicate(x: X, c: Controller<X>, p: (X) -> Unit) {}
fun main(a: A<*>, c: C) {
// Without having `is` check
// This PCLA/BI call works in the same way both in K1 and K2
val x1 = generate {
predicate(a, this) { x ->
// x is B
@@ -25,13 +27,19 @@ fun main(a: A<*>, c: C) {
<!DEBUG_INFO_EXPRESSION_TYPE("CommonSupertype")!>x1<!>
// But introducing `is` on the expression of `Xv` type as LHS and a bare type on RHS
// Leads to an early fixation of Xv to the current result type (A<*>) and automatically it leads to Sv fixation, too
// This case works differently in K1 (BI) and in K2 (PCLA), but in both cases it's red code
// Without the last `yield` call, it would be even green in K2
val x2 = generate {
predicate(a, this) { x ->
x is <!NO_TYPE_ARGUMENTS_ON_RHS!>B<!>
x is B
}
yield(c)
// For Sv we've got an EQUALITY constraint to A<*>
// Thus not allowing C type here
yield(<!ARGUMENT_TYPE_MISMATCH!>c<!>)
}
<!DEBUG_INFO_EXPRESSION_TYPE("CommonSupertype")!>x2<!>
<!DEBUG_INFO_EXPRESSION_TYPE("A<*>")!>x2<!>
}
@@ -15,6 +15,8 @@ interface C : CommonSupertype
fun <X> predicate(x: X, c: Controller<X>, p: (X) -> Unit) {}
fun main(a: A<*>, c: C) {
// Without having `is` check
// This PCLA/BI call works in the same way both in K1 and K2
val x1 = generate {
predicate(a, this) { x ->
// x is B
@@ -25,11 +27,17 @@ fun main(a: A<*>, c: C) {
<!DEBUG_INFO_EXPRESSION_TYPE("CommonSupertype")!>x1<!>
// But introducing `is` on the expression of `Xv` type as LHS and a bare type on RHS
// Leads to an early fixation of Xv to the current result type (A<*>) and automatically it leads to Sv fixation, too
// This case works differently in K1 (BI) and in K2 (PCLA), but in both cases it's red code
// Without the last `yield` call, it would be even green in K2
val x2 = generate {
predicate(a, this) { x ->
<!USELESS_IS_CHECK!>x is <!NO_TYPE_ARGUMENTS_ON_RHS!>B<!><!>
}
// For Sv we've got an EQUALITY constraint to A<*>
// Thus not allowing C type here
yield(c)
}