NI: Support forking inference with heuristics

Mostly, it only affects FIR

It partially allows to consider several variance of constraints like
A<Int> & A<T> <: A<X_var> that are mostly brought by smart casts

^KT-49542 Fixed
^KT-50489 Relates
This commit is contained in:
Denis.Zharkov
2021-12-24 14:24:19 +03:00
committed by teamcity
parent 62673c7e1b
commit a33d9df0cd
28 changed files with 401 additions and 11 deletions
@@ -0,0 +1,25 @@
// SKIP_TXT
// !DIAGNOSTICS: -UNUSED_VARIABLE
interface A<E> {
fun foo(): E
}
interface B : A<Int>
interface C : A<Long>
fun <T> bar(a: A<T>, w: T) {
baz(a, w) // OK in FE1.0
if (a is B) {
baz(a, 1) // OK in FE1.0
baz(a, w) // Type mismatch: Required Int, but found E
<!INFERENCE_UNSUCCESSFUL_FORK("it(B & A<T>) <: A<TypeVariable(F)>")!>baz<!>(a, "")
}
if (a is B || a is C) {
baz(a, w) // OK in FE 1.0 (Smart cast doesn't work), fail at FIR: it infers F to `LBU(Int, Long)` and then `w` is considered inapplicable
}
}
fun <F> baz(a: A<F>, f: F) {}
@@ -0,0 +1,25 @@
// SKIP_TXT
// !DIAGNOSTICS: -UNUSED_VARIABLE
interface A<E> {
fun foo(): E
}
interface B : A<Int>
interface C : A<Long>
fun <T> bar(a: A<T>, w: T) {
baz(a, w) // OK in FE1.0
if (a is B) {
baz(<!DEBUG_INFO_SMARTCAST!>a<!>, 1) // OK in FE1.0
baz(<!DEBUG_INFO_SMARTCAST!>a<!>, <!TYPE_MISMATCH!>w<!>) // Type mismatch: Required Int, but found E
baz(<!DEBUG_INFO_SMARTCAST!>a<!>, <!TYPE_MISMATCH!>""<!>)
}
if (a is B || a is C) {
baz(a, w) // OK in FE 1.0 (Smart cast doesn't work), fail at FIR: it infers F to `LBU(Int, Long)` and then `w` is considered inapplicable
}
}
fun <F> baz(a: A<F>, f: F) {}
@@ -0,0 +1,9 @@
// FIR_IDENTICAL
// SKIP_TXT
import java.util.*
val a = ArrayList<String>()
fun foo(l: List<String>) {
a.plusAssign(l)
}