K2: Support inference case with a mix of smart-cast and expected type

The idea is that we should not fix (i.e. choose any of the fork branches)
on the stage of candidate processing before completion, but it's enough
just to check that current state can be converged to success.

And when completion starts, and we add expected type to the system,
we've got more information to choose the correct fork branch.

NB: The old `processForkConstraints` is being called just
at the beginning of the completion phase.

^KT-43296 In Progress
This commit is contained in:
Denis.Zharkov
2022-11-01 19:21:16 +01:00
committed by Space Team
parent 77e197d46a
commit 715a73c8fb
9 changed files with 118 additions and 6 deletions
@@ -0,0 +1,28 @@
// SKIP_TXT
interface Slice<V>
interface A
interface B : A
interface C : A
val SL0: Slice<A> = TODO()
val SL1: Slice<B> = TODO()
val SL2: Slice<C> = TODO()
fun <X> foo(s: Slice<X>): X? {
if (s.hashCode() == 0) {
return bar(s)
}
if (s === SL0) {
return bar(s)
}
if (s === SL1 || s === SL2) {
return bar(s)
}
return null
}
fun <Y> bar(w: Slice<Y>): Y? = null
@@ -0,0 +1,28 @@
// SKIP_TXT
interface Slice<V>
interface A
interface B : A
interface C : A
val SL0: Slice<A> = TODO()
val SL1: Slice<B> = TODO()
val SL2: Slice<C> = TODO()
fun <X> foo(s: Slice<X>): X? {
if (s.hashCode() == 0) {
return bar(s)
}
if (s === SL0) {
return <!TYPE_MISMATCH, TYPE_MISMATCH!>bar(<!DEBUG_INFO_SMARTCAST!>s<!>)<!>
}
if (s === SL1 || s === SL2) {
return bar(s)
}
return null
}
fun <Y> bar(w: Slice<Y>): Y? = null
@@ -19,7 +19,7 @@ fun <X> InvBase<X>.myLastInv(): X = TODO()
fun <T> fooInv(x: InvBase<T>) {
if (x is InvDerived<*>) {
val l: T = <!INITIALIZER_TYPE_MISMATCH, TYPE_MISMATCH!>x.myLastInv()<!> // required T, found Cap(*). Only in NI
val l: T = x.myLastInv() // required T, found Cap(*). Only in NI
}
}