[FIR] Resolve elvis call as special synthetic call

Before that commit we desugared `a ?: b` as

when (val elvis = a) {
    null -> b
    else -> elvis
}

It was incorrect, because `a` should be resolved in dependent mode,
  but when it was `elvis` initializer it was resolved in independent
  mode, so we can't infer type for `a` in some complex cases
This commit is contained in:
Dmitriy Novozhilov
2020-06-30 15:31:24 +03:00
parent b49b3245af
commit 102c9c08d0
48 changed files with 1560 additions and 1828 deletions
@@ -0,0 +1,18 @@
// ISSUE: KT-39074
interface A
interface B : A {
fun bar()
}
fun <K : A> materialize(): K? = null!!
fun foo(b: B, cond: Boolean) {
val x = // inferred as A
if (cond)
b
else
materialize() ?: return
x.bar()
}
@@ -6,25 +6,17 @@ FILE: ifElvisReturn.kt
}
public final fun <K : R|A|> materialize(): R|K?| {
^materialize R|kotlin/TODO|()
^materialize Null(null)!!
}
public final fun foo(b: R|B|): R|kotlin/Unit| {
lval x: R|A| = when () {
CMP(>, R|<local>/b|.R|kotlin/Any.hashCode|().R|kotlin/Int.compareTo|(Int(0))) -> {
public final fun foo(b: R|B|, cond: R|kotlin/Boolean|): R|kotlin/Unit| {
lval x: R|B| = when () {
R|<local>/cond| -> {
R|<local>/b|
}
else -> {
when (lval <elvis>: R|A?| = R|/materialize|<R|A|>()) {
==($subj$, Null(null)) -> {
^foo Unit
}
else -> {
R|<local>/<elvis>|
}
}
R|/materialize|<R|kotlin/Nothing|>() ?: ^foo Unit
}
}
R|<local>/x|.<Unresolved name: bar>#()
R|<local>/x|.R|/B.bar|()
}
@@ -1,15 +1,7 @@
FILE: MapCompute.kt
public final fun <D> R|kotlin/collections/MutableMap<kotlin/String, kotlin/collections/MutableSet<D>>|.initAndAdd(key: R|kotlin/String|, value: R|D|): R|kotlin/Unit| {
this@R|/initAndAdd|.R|FakeOverride<kotlin/collections/MutableMap.compute: R|kotlin/collections/MutableSet<D>?|>|(R|<local>/key|, <L> = compute@fun <anonymous>(_: R|ft<kotlin/String, kotlin/String?>!|, maybeValues: R|ft<kotlin/collections/MutableSet<D>, kotlin/collections/MutableSet<D>?>!|): R|ft<kotlin/collections/MutableSet<D>, kotlin/collections/MutableSet<D>?>!| {
lval setOfValues: R|kotlin/collections/MutableSet<D>| = when (lval <elvis>: R|ft<kotlin/collections/MutableSet<D>, kotlin/collections/MutableSet<D>?>!| = R|<local>/maybeValues|) {
==($subj$, Null(null)) -> {
R|kotlin/collections/mutableSetOf|<R|D|>()
}
else -> {
R|<local>/<elvis>|
}
}
lval setOfValues: R|kotlin/collections/MutableSet<D>| = R|<local>/maybeValues| ?: R|kotlin/collections/mutableSetOf|<R|D|>()
R|<local>/setOfValues|.R|FakeOverride<kotlin/collections/MutableSet.add: R|kotlin/Boolean|>|(R|<local>/value|)
^ R|<local>/setOfValues|
}