FIR checker: substitute type parameters in dispatch receiver type

Consider the following code:

```
fun test(a: List<String>) {
  a.first()
}
```

The dispatch receiver type of `first` in this case is `List<T>` before
this change. After this change, it's `List<String>`.

In addition, this change also replace the dispatch receiver type with
the more specific type if available. For example, consider the following

```
class MyList: ArrayList<String>()

fun test(a: MyList) {
  a.get(0)
}
```
The dispatch receiver type of `get` is `MyList`, instead of
`ArrayList<String>`. That is, a fake override is created in this case.
This commit is contained in:
Tianyu Geng
2021-08-06 14:56:37 -07:00
committed by teamcityserver
parent c047adbaec
commit 765cad8448
61 changed files with 342 additions and 145 deletions
@@ -18,10 +18,10 @@ FILE: bareTypes2.kt
}
public final fun test(x: R|A<*>|): R|kotlin/Unit| {
when ((R|<local>/x| as? R|C|)?.{ $subj$.R|/A.field| }) {
when ((R|<local>/x| as? R|C|)?.{ $subj$.R|SubstitutionOverride</C.field: R|kotlin/Any|>| }) {
($subj$ is R|kotlin/String|) -> {
when () {
==((R|<local>/x| as? R|B<*>|)?.{ $subj$.R|/A.cond| }, Boolean(true)) -> {
==((R|<local>/x| as? R|B<*>|)?.{ $subj$.R|SubstitutionOverride</B.cond: R|kotlin/Boolean|>| }, Boolean(true)) -> {
R|<local>/x|.R|/C.foo|()
}
}
@@ -204,7 +204,7 @@ digraph complex_kt {
color=blue
62 [label="Enter loop condition"];
63 [label="Access variable R|<local>/<iterator>|"];
64 [label="Function call: R|<local>/<iterator>|.R|kotlin/collections/Iterator.hasNext|()"];
64 [label="Function call: R|<local>/<iterator>|.R|SubstitutionOverride<kotlin/collections/Iterator.hasNext: R|kotlin/Boolean|>|()"];
65 [label="Exit loop condition"];
}
subgraph cluster_23 {
@@ -27,7 +27,7 @@ FILE: complex.kt
public final inline fun <reified T : R|kotlin/Any|> R|kotlin/collections/List<*>|.firstIsInstanceOrNull(): R|T?| {
{
lval <iterator>: R|kotlin/collections/Iterator<kotlin/Any?>| = this@R|/firstIsInstanceOrNull|.R|SubstitutionOverride<kotlin/collections/List.iterator: R|kotlin/collections/Iterator<CapturedType(*)>|>|()
while(R|<local>/<iterator>|.R|kotlin/collections/Iterator.hasNext|()) {
while(R|<local>/<iterator>|.R|SubstitutionOverride<kotlin/collections/Iterator.hasNext: R|kotlin/Boolean|>|()) {
lval element: R|kotlin/Any?| = R|<local>/<iterator>|.R|SubstitutionOverride<kotlin/collections/Iterator.next: R|kotlin/Any?|>|()
when () {
(R|<local>/element| is R|T|) -> {
+1 -1
View File
@@ -133,7 +133,7 @@ digraph loops_kt {
color=blue
45 [label="Enter loop condition"];
46 [label="Access variable R|<local>/<iterator>|"];
47 [label="Function call: R|<local>/<iterator>|.R|kotlin/collections/Iterator.hasNext|()"];
47 [label="Function call: R|<local>/<iterator>|.R|SubstitutionOverride<kotlin/collections/IntIterator.hasNext: R|kotlin/Boolean|>|()"];
48 [label="Exit loop condition"];
}
subgraph cluster_17 {
@@ -16,7 +16,7 @@ FILE: loops.kt
public final fun testFor(x: R|kotlin/Any?|): R|kotlin/Unit| {
{
lval <iterator>: R|kotlin/collections/IntIterator| = Int(0).R|kotlin/Int.rangeTo|(Int(5)).R|kotlin/ranges/IntProgression.iterator|()
while(R|<local>/<iterator>|.R|kotlin/collections/Iterator.hasNext|()) {
while(R|<local>/<iterator>|.R|SubstitutionOverride<kotlin/collections/IntIterator.hasNext: R|kotlin/Boolean|>|()) {
lval i: R|kotlin/Int| = R|<local>/<iterator>|.R|kotlin/collections/IntIterator.next|()
lval y: R|kotlin/Boolean| = (R|<local>/x| is R|kotlin/String|)
}
@@ -23,11 +23,11 @@ FILE: qualifiedSupertypeExtendedByOtherSupertype.kt
}
public final fun test(): R|kotlin/Unit| {
this@R|/Test|.super<R|IBase<kotlin/String>|>.R|/IBase.foo|()
this@R|/Test|.super<R|IBase<kotlin/String>|>.R|/IBase.bar|()
this@R|/Test|.super<R|IDerived<kotlin/String>|>.R|/IDerived.foo|()
this@R|/Test|.super<R|IDerived<kotlin/String>|>.R|/IBase.bar|()
this@R|/Test|.super<R|IDerived<kotlin/String>|>.R|/IDerived.qux|()
this@R|/Test|.super<R|IBase<kotlin/String>|>.R|SubstitutionOverride</IBase.foo: R|kotlin/Unit|>|()
this@R|/Test|.super<R|IBase<kotlin/String>|>.R|SubstitutionOverride</IBase.bar: R|kotlin/Unit|>|()
this@R|/Test|.super<R|IDerived<kotlin/String>|>.R|SubstitutionOverride</IDerived.foo: R|kotlin/Unit|>|()
this@R|/Test|.super<R|IDerived<kotlin/String>|>.R|SubstitutionOverride</IDerived.bar: R|kotlin/Unit|>|()
this@R|/Test|.super<R|IDerived<kotlin/String>|>.R|SubstitutionOverride</IDerived.qux: R|kotlin/Unit|>|()
}
}
@@ -37,13 +37,13 @@ FILE: qualifiedSupertypeExtendedByOtherSupertype.kt
}
public final fun test(): R|kotlin/Unit| {
this@R|/Test2|.super<R|IBase<kotlin/String>|>.R|/IBase.foo|()
this@R|/Test2|.super<R|IBase<kotlin/String>|>.R|/IBase.bar|()
this@R|/Test2|.super<R|IBase<kotlin/String>|>.R|/IBase.foo|()
this@R|/Test2|.super<R|IBase<kotlin/String>|>.R|/IBase.bar|()
this@R|/Test2|.super<R|IDerived<kotlin/String>|>.R|/IDerived.foo|()
this@R|/Test2|.super<R|IDerived<kotlin/String>|>.R|/IBase.bar|()
this@R|/Test2|.super<R|IDerived<kotlin/String>|>.R|/IDerived.qux|()
this@R|/Test2|.super<R|IBase<kotlin/String>|>.R|SubstitutionOverride</IBase.foo: R|kotlin/Unit|>|()
this@R|/Test2|.super<R|IBase<kotlin/String>|>.R|SubstitutionOverride</IBase.bar: R|kotlin/Unit|>|()
this@R|/Test2|.super<R|IBase<kotlin/String>|>.R|SubstitutionOverride</IBase.foo: R|kotlin/Unit|>|()
this@R|/Test2|.super<R|IBase<kotlin/String>|>.R|SubstitutionOverride</IBase.bar: R|kotlin/Unit|>|()
this@R|/Test2|.super<R|IDerived<kotlin/String>|>.R|SubstitutionOverride</IDerived.foo: R|kotlin/Unit|>|()
this@R|/Test2|.super<R|IDerived<kotlin/String>|>.R|SubstitutionOverride</IDerived.bar: R|kotlin/Unit|>|()
this@R|/Test2|.super<R|IDerived<kotlin/String>|>.R|SubstitutionOverride</IDerived.qux: R|kotlin/Unit|>|()
}
}
@@ -22,7 +22,7 @@ FILE: enumValues.kt
lval values: R|kotlin/Array<MyEnum>| = Q|MyEnum|.R|/MyEnum.values|()
{
lval <iterator>: R|kotlin/collections/Iterator<MyEnum>| = R|<local>/values|.R|SubstitutionOverride<kotlin/Array.iterator: R|kotlin/collections/Iterator<MyEnum>|>|()
while(R|<local>/<iterator>|.R|kotlin/collections/Iterator.hasNext|()) {
while(R|<local>/<iterator>|.R|SubstitutionOverride<kotlin/collections/Iterator.hasNext: R|kotlin/Boolean|>|()) {
lval value: R|MyEnum| = R|<local>/<iterator>|.R|SubstitutionOverride<kotlin/collections/Iterator.next: R|MyEnum|>|()
R|<local>/value|.R|/MyEnum.bar|()
}
@@ -5,7 +5,7 @@ FILE: test.kt
}
public final override fun getLookupString(): R|kotlin/String| {
^getLookupString this@R|/MyDecorator|.R|/MyDecorator.delegate|.R|/LookupElement.lookupString|
^getLookupString this@R|/MyDecorator|.R|/Decorator.delegate|.R|/LookupElement.lookupString|
}
}
@@ -30,6 +30,6 @@ FILE: importedReceiver.kt
(Q|My|, String()).R|/My.bar|<R|kotlin/String|>()
Q|My|.R|/My.baz|()
(Q|My|, Boolean(true)).R|/My.gau|()
Q|My|.R|/Your.wat|()
Q|My|.R|SubstitutionOverride</My.wat: R|kotlin/Unit|>|()
(Q|My|, Boolean(false)).R|SubstitutionOverride</My.watwat: R|kotlin/Unit|>|<R|kotlin/Boolean|>()
}
@@ -68,7 +68,7 @@ FILE: CanBeValChecker.kt
R|<local>/a| = Int(1)
{
lval <iterator>: R|kotlin/collections/IntIterator| = Int(1).R|kotlin/Int.rangeTo|(Int(10)).R|kotlin/ranges/IntProgression.iterator|()
while(R|<local>/<iterator>|.R|kotlin/collections/Iterator.hasNext|()) {
while(R|<local>/<iterator>|.R|SubstitutionOverride<kotlin/collections/IntIterator.hasNext: R|kotlin/Boolean|>|()) {
lval i: R|kotlin/Int| = R|<local>/<iterator>|.R|kotlin/collections/IntIterator.next|()
R|kotlin/io/print|(R|<local>/i|)
}
@@ -171,7 +171,7 @@ FILE: CanBeValChecker.kt
lvar a: R|kotlin/String?|
lval unused: R|kotlin/Int| = Int(0)
when () {
==(R|<local>/args|.R|kotlin/Array.size|, Int(1)) -> {
==(R|<local>/args|.R|SubstitutionOverride<kotlin/Array.size: R|kotlin/Int|>|, Int(1)) -> {
R|<local>/a| = R|<local>/args|.R|SubstitutionOverride<kotlin/Array.get: R|kotlin/String?|>|(Int(0))
}
else -> {
@@ -2,7 +2,7 @@ FILE: NoWarning.kt
public final fun foo(): R|kotlin/Unit| {
{
lval <iterator>: R|kotlin/collections/IntIterator| = Int(1).R|kotlin/Int.rangeTo|(Int(2)).R|kotlin/ranges/IntProgression.iterator|()
while(R|<local>/<iterator>|.R|kotlin/collections/Iterator.hasNext|()) {
while(R|<local>/<iterator>|.R|SubstitutionOverride<kotlin/collections/IntIterator.hasNext: R|kotlin/Boolean|>|()) {
lval i: R|kotlin/Int| = R|<local>/<iterator>|.R|kotlin/collections/IntIterator.next|()
}
@@ -19,7 +19,7 @@ FILE: NoWarning.kt
public final fun backward(): R|kotlin/Unit| {
{
lval <iterator>: R|kotlin/collections/IntIterator| = Int(2).R|kotlin/ranges/downTo|(Int(1)).R|kotlin/ranges/IntProgression.iterator|()
while(R|<local>/<iterator>|.R|kotlin/collections/Iterator.hasNext|()) {
while(R|<local>/<iterator>|.R|SubstitutionOverride<kotlin/collections/IntIterator.hasNext: R|kotlin/Boolean|>|()) {
lval i: R|kotlin/Int| = R|<local>/<iterator>|.R|kotlin/collections/IntIterator.next|()
}
@@ -36,7 +36,7 @@ FILE: NoWarning.kt
public final fun until(): R|kotlin/Unit| {
{
lval <iterator>: R|kotlin/collections/IntIterator| = Int(1).R|kotlin/ranges/until|(Int(2)).R|kotlin/ranges/IntProgression.iterator|()
while(R|<local>/<iterator>|.R|kotlin/collections/Iterator.hasNext|()) {
while(R|<local>/<iterator>|.R|SubstitutionOverride<kotlin/collections/IntIterator.hasNext: R|kotlin/Boolean|>|()) {
lval i: R|kotlin/Int| = R|<local>/<iterator>|.R|kotlin/collections/IntIterator.next|()
}
@@ -2,7 +2,7 @@ FILE: Warning.kt
public final fun foo(): R|kotlin/Unit| {
{
lval <iterator>: R|kotlin/collections/IntIterator| = Int(2).R|kotlin/Int.rangeTo|(Int(1)).R|kotlin/ranges/IntProgression.iterator|()
while(R|<local>/<iterator>|.R|kotlin/collections/Iterator.hasNext|()) {
while(R|<local>/<iterator>|.R|SubstitutionOverride<kotlin/collections/IntIterator.hasNext: R|kotlin/Boolean|>|()) {
lval i: R|kotlin/Int| = R|<local>/<iterator>|.R|kotlin/collections/IntIterator.next|()
}
@@ -19,7 +19,7 @@ FILE: Warning.kt
public final fun backward(): R|kotlin/Unit| {
{
lval <iterator>: R|kotlin/collections/IntIterator| = Int(1).R|kotlin/ranges/downTo|(Int(2)).R|kotlin/ranges/IntProgression.iterator|()
while(R|<local>/<iterator>|.R|kotlin/collections/Iterator.hasNext|()) {
while(R|<local>/<iterator>|.R|SubstitutionOverride<kotlin/collections/IntIterator.hasNext: R|kotlin/Boolean|>|()) {
lval i: R|kotlin/Int| = R|<local>/<iterator>|.R|kotlin/collections/IntIterator.next|()
}
@@ -36,7 +36,7 @@ FILE: Warning.kt
public final fun until(): R|kotlin/Unit| {
{
lval <iterator>: R|kotlin/collections/IntIterator| = Int(1).R|kotlin/ranges/until|(Int(1)).R|kotlin/ranges/IntProgression.iterator|()
while(R|<local>/<iterator>|.R|kotlin/collections/Iterator.hasNext|()) {
while(R|<local>/<iterator>|.R|SubstitutionOverride<kotlin/collections/IntIterator.hasNext: R|kotlin/Boolean|>|()) {
lval i: R|kotlin/Int| = R|<local>/<iterator>|.R|kotlin/collections/IntIterator.next|()
}
@@ -5,7 +5,7 @@ FILE: manyLocalVariables.kt
lvar c: R|kotlin/Int| = Int(3)
{
lval <iterator>: R|kotlin/collections/IntIterator| = Int(0).R|kotlin/Int.rangeTo|(Int(5)).R|kotlin/ranges/IntProgression.iterator|()
while(R|<local>/<iterator>|.R|kotlin/collections/Iterator.hasNext|()) {
while(R|<local>/<iterator>|.R|SubstitutionOverride<kotlin/collections/IntIterator.hasNext: R|kotlin/Boolean|>|()) {
lval i: R|kotlin/Int| = R|<local>/<iterator>|.R|kotlin/collections/IntIterator.next|()
when () {
==(R|<local>/a|, Int(2)) -> {
+1 -1
View File
@@ -10,7 +10,7 @@ FILE: fib.kt
lvar prev: R|kotlin/Int| = Int(1)
{
lval <iterator>: R|kotlin/collections/IntIterator| = Int(2).R|kotlin/Int.rangeTo|(R|<local>/n|).R|kotlin/ranges/IntProgression.iterator|()
while(R|<local>/<iterator>|.R|kotlin/collections/Iterator.hasNext|()) {
while(R|<local>/<iterator>|.R|SubstitutionOverride<kotlin/collections/IntIterator.hasNext: R|kotlin/Boolean|>|()) {
lval i: R|kotlin/Int| = R|<local>/<iterator>|.R|kotlin/collections/IntIterator.next|()
lval temp: R|kotlin/Int| = R|<local>/current|
R|<local>/current| = R|<local>/current|.R|kotlin/Int.plus|(R|<local>/prev|)
@@ -7,7 +7,7 @@ FILE: nestedExtensionFunctionType.kt
public final fun test_1(a: R|A|, ys: R|kotlin/collections/List<@ExtensionFunctionType kotlin/Function1<A, kotlin/Unit>>|): R|kotlin/Unit| {
{
lval <iterator>: R|kotlin/collections/Iterator<@ExtensionFunctionType kotlin/Function1<A, kotlin/Unit>>| = R|<local>/ys|.R|SubstitutionOverride<kotlin/collections/List.iterator: R|kotlin/collections/Iterator<@ExtensionFunctionType kotlin/Function1<A, kotlin/Unit>>|>|()
while(R|<local>/<iterator>|.R|kotlin/collections/Iterator.hasNext|()) {
while(R|<local>/<iterator>|.R|SubstitutionOverride<kotlin/collections/Iterator.hasNext: R|kotlin/Boolean|>|()) {
lval y: R|(A) -> kotlin/Unit| = R|<local>/<iterator>|.R|SubstitutionOverride<kotlin/collections/Iterator.next: R|(A) -> kotlin/Unit|>|()
R|<local>/y|.R|SubstitutionOverride<kotlin/Function1.invoke: R|kotlin/Unit|>|(R|<local>/a|)
}
@@ -18,7 +18,7 @@ FILE: nestedExtensionFunctionType.kt
public final fun test_2(a: R|A|, vararg zs: R|kotlin/Array<out @ExtensionFunctionType kotlin/Function1<A, kotlin/Unit>>|): R|kotlin/Unit| {
{
lval <iterator>: R|kotlin/collections/Iterator<@ExtensionFunctionType kotlin/Function1<A, kotlin/Unit>>| = R|<local>/zs|.R|SubstitutionOverride<kotlin/Array.iterator: R|kotlin/collections/Iterator<CapturedType(out @ExtensionFunctionType kotlin/Function1<A, kotlin/Unit>)>|>|()
while(R|<local>/<iterator>|.R|kotlin/collections/Iterator.hasNext|()) {
while(R|<local>/<iterator>|.R|SubstitutionOverride<kotlin/collections/Iterator.hasNext: R|kotlin/Boolean|>|()) {
lval z: R|(A) -> kotlin/Unit| = R|<local>/<iterator>|.R|SubstitutionOverride<kotlin/collections/Iterator.next: R|(A) -> kotlin/Unit|>|()
R|<local>/z|.R|SubstitutionOverride<kotlin/Function1.invoke: R|kotlin/Unit|>|(R|<local>/a|)
}
@@ -13,9 +13,9 @@ FILE: compilerPhase.kt
}
public final inline fun <R, D> R|PhaserState<D>|.downlevel(nlevels: R|kotlin/Int|, block: R|() -> R|): R|R| {
this@R|/downlevel|.R|/PhaserState.depth| = this@R|/downlevel|.R|/PhaserState.depth|.R|kotlin/Int.plus|(R|<local>/nlevels|)
this@R|/downlevel|.R|SubstitutionOverride</PhaserState.depth: R|kotlin/Int|>| = this@R|/downlevel|.R|SubstitutionOverride</PhaserState.depth: R|kotlin/Int|>|.R|kotlin/Int.plus|(R|<local>/nlevels|)
lval result: R|R| = R|<local>/block|.R|SubstitutionOverride<kotlin/Function0.invoke: R|R|>|()
this@R|/downlevel|.R|/PhaserState.depth| = this@R|/downlevel|.R|/PhaserState.depth|.R|kotlin/Int.minus|(R|<local>/nlevels|)
this@R|/downlevel|.R|SubstitutionOverride</PhaserState.depth: R|kotlin/Int|>| = this@R|/downlevel|.R|SubstitutionOverride</PhaserState.depth: R|kotlin/Int|>|.R|kotlin/Int.minus|(R|<local>/nlevels|)
^downlevel R|<local>/result|
}
public abstract interface CompilerPhase<in Context : R|CommonBackendContext|, Input, Output> : R|kotlin/Any| {
@@ -22,11 +22,11 @@ FILE: main.kt
}
public final fun main(d1: R|D1|, e1: R|E1|, d2: R|D2|, e2: R|E2|): R|kotlin/Unit| {
R|<local>/d1|.R|/D1.foo|
R|<local>/d1|.R|/KB.foo|
R|<local>/d1|.<Unresolved name: bar>#
R|<local>/e1|.R|/E1.foo|
R|<local>/e1|.<Unresolved name: bar>#
R|<local>/d2|.R|/D2.foo|
R|<local>/d2|.R|/KB.foo|
R|<local>/d2|.<Unresolved name: bar>#
R|<local>/e2|.R|/E2.foo|
R|<local>/e2|.<Unresolved name: bar>#
@@ -54,7 +54,7 @@ digraph boundSmartcastsInBranches_kt {
color=blue
18 [label="Enter loop condition"];
19 [label="Access variable R|<local>/<iterator>|"];
20 [label="Function call: R|<local>/<iterator>|.R|kotlin/collections/Iterator.hasNext|()"];
20 [label="Function call: R|<local>/<iterator>|.R|SubstitutionOverride<kotlin/collections/Iterator.hasNext: R|kotlin/Boolean|>|()"];
21 [label="Exit loop condition"];
}
subgraph cluster_8 {
@@ -84,7 +84,7 @@ digraph boundSmartcastsInBranches_kt {
35 [label="Enter block"];
36 [label="Access variable R|<local>/a|"];
37 [label="Assignment: R|<local>/goodA|"];
38 [label="Jump: continue@@@[R|<local>/<iterator>|.R|kotlin/collections/Iterator.hasNext|()] "];
38 [label="Jump: continue@@@[R|<local>/<iterator>|.R|SubstitutionOverride<kotlin/collections/Iterator.hasNext: R|kotlin/Boolean|>|()] "];
39 [label="Stub" style="filled" fillcolor=gray];
40 [label="Exit block" style="filled" fillcolor=gray];
}
@@ -12,12 +12,12 @@ FILE: boundSmartcastsInBranches.kt
lvar goodA: R|A?| = Null(null)
{
lval <iterator>: R|kotlin/collections/Iterator<A>| = R|<local>/list|.R|SubstitutionOverride<kotlin/collections/List.iterator: R|kotlin/collections/Iterator<A>|>|()
while(R|<local>/<iterator>|.R|kotlin/collections/Iterator.hasNext|()) {
while(R|<local>/<iterator>|.R|SubstitutionOverride<kotlin/collections/Iterator.hasNext: R|kotlin/Boolean|>|()) {
lval a: R|A| = R|<local>/<iterator>|.R|SubstitutionOverride<kotlin/collections/Iterator.next: R|A|>|()
when () {
==(R|<local>/goodA|, Null(null)) -> {
R|<local>/goodA| = R|<local>/a|
continue@@@[R|<local>/<iterator>|.R|kotlin/collections/Iterator.hasNext|()]
continue@@@[R|<local>/<iterator>|.R|SubstitutionOverride<kotlin/collections/Iterator.hasNext: R|kotlin/Boolean|>|()]
}
}
@@ -51,7 +51,7 @@ digraph implicitReceiverAsWhenSubject_kt {
color=blue
23 [label="Enter block"];
24 [label="Access variable this@R|/test_1|"];
25 [label="Access variable R|kotlin/collections/List.size|"];
25 [label="Access variable R|SubstitutionOverride<kotlin/collections/List.size: R|kotlin/Int|>|"];
26 [label="Exit block"];
}
27 [label="Exit when branch result"];
@@ -59,7 +59,7 @@ digraph implicitReceiverAsWhenSubject_kt {
}
29 [label="Jump: ^test_1 when (this@R|/test_1|) {
($subj$ is R|kotlin/collections/List<*>|) -> {
this@R|/test_1|.R|kotlin/collections/List.size|
this@R|/test_1|.R|SubstitutionOverride<kotlin/collections/List.size: R|kotlin/Int|>|
}
($subj$ is R|kotlin/String|) -> {
this@R|/test_1|.R|kotlin/String.length|
@@ -159,9 +159,9 @@ digraph implicitReceiverAsWhenSubject_kt {
color=blue
59 [label="Enter block"];
60 [label="Access variable R|<local>/x|"];
61 [label="Access variable R|kotlin/collections/List.size|"];
61 [label="Access variable R|SubstitutionOverride<kotlin/collections/List.size: R|kotlin/Int|>|"];
62 [label="Access variable this@R|/test_2|"];
63 [label="Access variable R|kotlin/collections/List.size|"];
63 [label="Access variable R|SubstitutionOverride<kotlin/collections/List.size: R|kotlin/Int|>|"];
64 [label="Exit block"];
}
65 [label="Exit when branch result"];
@@ -169,8 +169,8 @@ digraph implicitReceiverAsWhenSubject_kt {
}
67 [label="Jump: ^test_2 when (lval x: R|kotlin/Any| = this@R|/test_2|) {
($subj$ is R|kotlin/collections/List<*>|) -> {
R|<local>/x|.R|kotlin/collections/List.size|
this@R|/test_2|.R|kotlin/collections/List.size|
R|<local>/x|.R|SubstitutionOverride<kotlin/collections/List.size: R|kotlin/Int|>|
this@R|/test_2|.R|SubstitutionOverride<kotlin/collections/List.size: R|kotlin/Int|>|
}
($subj$ is R|kotlin/String|) -> {
R|<local>/x|.R|kotlin/String.length|
@@ -2,7 +2,7 @@ FILE: implicitReceiverAsWhenSubject.kt
public final fun R|kotlin/Any|.test_1(): R|kotlin/Int| {
^test_1 when (this@R|/test_1|) {
($subj$ is R|kotlin/collections/List<*>|) -> {
this@R|/test_1|.R|kotlin/collections/List.size|
this@R|/test_1|.R|SubstitutionOverride<kotlin/collections/List.size: R|kotlin/Int|>|
}
($subj$ is R|kotlin/String|) -> {
this@R|/test_1|.R|kotlin/String.length|
@@ -16,8 +16,8 @@ FILE: implicitReceiverAsWhenSubject.kt
public final fun R|kotlin/Any|.test_2(): R|kotlin/Int| {
^test_2 when (lval x: R|kotlin/Any| = this@R|/test_2|) {
($subj$ is R|kotlin/collections/List<*>|) -> {
R|<local>/x|.R|kotlin/collections/List.size|
this@R|/test_2|.R|kotlin/collections/List.size|
R|<local>/x|.R|SubstitutionOverride<kotlin/collections/List.size: R|kotlin/Int|>|
this@R|/test_2|.R|SubstitutionOverride<kotlin/collections/List.size: R|kotlin/Int|>|
}
($subj$ is R|kotlin/String|) -> {
R|<local>/x|.R|kotlin/String.length|
@@ -547,7 +547,7 @@ digraph implicitReceivers_kt {
subgraph cluster_52 {
color=blue
202 [label="Enter block"];
203 [label="Access variable R|kotlin/collections/List.size|"];
203 [label="Access variable R|SubstitutionOverride<kotlin/collections/List.size: R|kotlin/Int|>|"];
204 [label="Exit block"];
}
205 [label="Exit when branch result"];
@@ -555,7 +555,7 @@ digraph implicitReceivers_kt {
}
207 [label="Jump: ^test_5 when () {
(this@R|/test_5| is R|kotlin/collections/List<*>|) -> {
this@R|/test_5|.R|kotlin/collections/List.size|
this@R|/test_5|.R|SubstitutionOverride<kotlin/collections/List.size: R|kotlin/Int|>|
}
(this@R|/test_5| is R|kotlin/String|) -> {
this@R|/test_5|.R|kotlin/String.length|
@@ -612,7 +612,7 @@ digraph implicitReceivers_kt {
212 [label="Enter block"];
213 [label="Access variable this@R|/test_6|"];
214 [label="Type operator: (this@R|/test_6| as R|kotlin/collections/List<*>|)"];
215 [label="Access variable R|kotlin/collections/List.size|"];
215 [label="Access variable R|SubstitutionOverride<kotlin/collections/List.size: R|kotlin/Int|>|"];
216 [label="Access variable this@R|/test_6|"];
217 [label="Type operator: (this@R|/test_6| as R|kotlin/String|)"];
218 [label="Access variable R|kotlin/String.length|"];
@@ -100,7 +100,7 @@ FILE: implicitReceivers.kt
public final fun R|kotlin/Any|.test_5(): R|kotlin/Int| {
^test_5 when () {
(this@R|/test_5| is R|kotlin/collections/List<*>|) -> {
this@R|/test_5|.R|kotlin/collections/List.size|
this@R|/test_5|.R|SubstitutionOverride<kotlin/collections/List.size: R|kotlin/Int|>|
}
(this@R|/test_5| is R|kotlin/String|) -> {
this@R|/test_5|.R|kotlin/String.length|
@@ -113,7 +113,7 @@ FILE: implicitReceivers.kt
}
public final fun R|kotlin/Any|.test_6(): R|kotlin/Unit| {
(this@R|/test_6| as R|kotlin/collections/List<*>|)
this@R|/test_6|.R|kotlin/collections/List.size|
this@R|/test_6|.R|SubstitutionOverride<kotlin/collections/List.size: R|kotlin/Int|>|
(this@R|/test_6| as R|kotlin/String|)
this@R|/test_6|.R|kotlin/String.length|
}
@@ -181,7 +181,7 @@ digraph smartcastToNothing_kt {
color=blue
61 [label="Enter loop condition"];
62 [label="Access variable R|<local>/<iterator>|"];
63 [label="Function call: R|<local>/<iterator>|.R|kotlin/collections/Iterator.hasNext|()"];
63 [label="Function call: R|<local>/<iterator>|.R|SubstitutionOverride<kotlin/collections/Iterator.hasNext: R|kotlin/Boolean|>|()"];
64 [label="Exit loop condition"];
}
subgraph cluster_19 {
@@ -213,7 +213,7 @@ digraph smartcastToNothing_kt {
subgraph cluster_23 {
color=blue
82 [label="Enter block" style="filled" fillcolor=gray];
83 [label="Jump: break@@@[R|<local>/<iterator>|.R|kotlin/collections/Iterator.hasNext|()] " style="filled" fillcolor=gray];
83 [label="Jump: break@@@[R|<local>/<iterator>|.R|SubstitutionOverride<kotlin/collections/Iterator.hasNext: R|kotlin/Boolean|>|()] " style="filled" fillcolor=gray];
84 [label="Stub" style="filled" fillcolor=gray];
85 [label="Exit block" style="filled" fillcolor=gray];
}
@@ -32,12 +32,12 @@ FILE: smartcastToNothing.kt
lvar s: R|A?| = Null(null)
{
lval <iterator>: R|kotlin/collections/Iterator<kotlin/Nothing>| = R|<local>/results|.R|SubstitutionOverride<kotlin/collections/List.iterator: R|kotlin/collections/Iterator<kotlin/Nothing>|>|()
while(R|<local>/<iterator>|.R|kotlin/collections/Iterator.hasNext|()) {
while(R|<local>/<iterator>|.R|SubstitutionOverride<kotlin/collections/Iterator.hasNext: R|kotlin/Boolean|>|()) {
lval result: R|kotlin/Nothing| = R|<local>/<iterator>|.R|SubstitutionOverride<kotlin/collections/Iterator.next: R|kotlin/Nothing|>|()
R|<local>/s| = R|<local>/result|
when () {
R|<local>/result|.<Unresolved name: b># -> {
break@@@[R|<local>/<iterator>|.R|kotlin/collections/Iterator.hasNext|()]
break@@@[R|<local>/<iterator>|.R|SubstitutionOverride<kotlin/collections/Iterator.hasNext: R|kotlin/Boolean|>|()]
}
}
@@ -11,7 +11,7 @@ FILE: varargInPrimaryConstructor.kt
public final fun test_1(foo: R|Foo|): R|kotlin/Unit| {
{
lval <iterator>: R|kotlin/collections/Iterator<kotlin/String>| = R|<local>/foo|.R|/Foo.strings|.R|SubstitutionOverride<kotlin/Array.iterator: R|kotlin/collections/Iterator<CapturedType(out kotlin/String)>|>|()
while(R|<local>/<iterator>|.R|kotlin/collections/Iterator.hasNext|()) {
while(R|<local>/<iterator>|.R|SubstitutionOverride<kotlin/collections/Iterator.hasNext: R|kotlin/Boolean|>|()) {
lval s: R|kotlin/String| = R|<local>/<iterator>|.R|SubstitutionOverride<kotlin/collections/Iterator.next: R|kotlin/String|>|()
R|<local>/s|.R|kotlin/String.length|
}
@@ -22,7 +22,7 @@ FILE: varargInPrimaryConstructor.kt
public final fun test_2(vararg strings: R|kotlin/Array<out kotlin/String>|): R|kotlin/Unit| {
{
lval <iterator>: R|kotlin/collections/Iterator<kotlin/String>| = R|<local>/strings|.R|SubstitutionOverride<kotlin/Array.iterator: R|kotlin/collections/Iterator<CapturedType(out kotlin/String)>|>|()
while(R|<local>/<iterator>|.R|kotlin/collections/Iterator.hasNext|()) {
while(R|<local>/<iterator>|.R|SubstitutionOverride<kotlin/collections/Iterator.hasNext: R|kotlin/Boolean|>|()) {
lval s: R|kotlin/String| = R|<local>/<iterator>|.R|SubstitutionOverride<kotlin/collections/Iterator.next: R|kotlin/String|>|()
R|<local>/s|.R|kotlin/String.length|
}
@@ -20,7 +20,7 @@ FILE: components.kt
public final fun foo(list: R|kotlin/collections/List<D>|): R|kotlin/Unit| {
{
lval <iterator>: R|kotlin/collections/Iterator<D>| = R|<local>/list|.R|SubstitutionOverride<kotlin/collections/List.iterator: R|kotlin/collections/Iterator<D>|>|()
while(R|<local>/<iterator>|.R|kotlin/collections/Iterator.hasNext|()) {
while(R|<local>/<iterator>|.R|SubstitutionOverride<kotlin/collections/Iterator.hasNext: R|kotlin/Boolean|>|()) {
lval <destruct>: R|D| = R|<local>/<iterator>|.R|SubstitutionOverride<kotlin/collections/Iterator.next: R|D|>|()
lval x: R|kotlin/Int| = R|<local>/<destruct>|.R|/D.component1|()
lval y: R|kotlin/String| = R|<local>/<destruct>|.R|/D.component2|()
@@ -143,7 +143,7 @@ digraph flow_kt {
color=blue
64 [label="Enter loop condition"];
65 [label="Access variable R|<local>/<iterator>|"];
66 [label="Function call: R|<local>/<iterator>|.R|kotlin/collections/Iterator.hasNext|()"];
66 [label="Function call: R|<local>/<iterator>|.R|SubstitutionOverride<kotlin/collections/IntIterator.hasNext: R|kotlin/Boolean|>|()"];
67 [label="Exit loop condition"];
}
subgraph cluster_20 {
@@ -28,7 +28,7 @@ FILE: flow.kt
Boolean(true) -> {
{
lval <iterator>: R|kotlin/collections/IntIterator| = Int(0).R|kotlin/Int.rangeTo|(Int(0)).R|kotlin/ranges/IntProgression.iterator|()
while(R|<local>/<iterator>|.R|kotlin/collections/Iterator.hasNext|()) {
while(R|<local>/<iterator>|.R|SubstitutionOverride<kotlin/collections/IntIterator.hasNext: R|kotlin/Boolean|>|()) {
lval i: R|kotlin/Int| = R|<local>/<iterator>|.R|kotlin/collections/IntIterator.next|()
R|<local>/x|.R|SubstitutionOverride<kotlin/Function0.invoke: R|kotlin/Unit|>|()
}
@@ -253,7 +253,7 @@ FILE: forLoopChecker.kt
{
lval <iterator>: R|kotlin/collections/Iterator<kotlin/Int>| = R|<local>/range1|.R|/Range1.iterator|()
while(R|<local>/<iterator>|.R|kotlin/collections/Iterator.hasNext|()) {
while(R|<local>/<iterator>|.R|SubstitutionOverride<kotlin/collections/Iterator.hasNext: R|kotlin/Boolean|>|()) {
lval i: R|kotlin/Int| = R|<local>/<iterator>|.R|SubstitutionOverride<kotlin/collections/Iterator.next: R|kotlin/Int|>|()
}
@@ -44,7 +44,7 @@ FILE: DeepCopyIrTree.kt
this@R|/DeepCopyIrTreeWithSymbols|.R|/DeepCopyIrTreeWithSymbols.typeRemapper|.R|/withinScope|<R|kotlin/Unit|>(this@R|/DeepCopyIrTreeWithSymbols.copyTypeParametersFrom|, <L> = withinScope@fun <anonymous>(): R|kotlin/Unit| <inline=Inline, kind=UNKNOWN> {
{
lval <iterator>: R|kotlin/collections/Iterator<kotlin/Pair<IrTypeParameter, IrTypeParameter>>| = this@R|/DeepCopyIrTreeWithSymbols.copyTypeParametersFrom|.R|/IrTypeParametersContainer.typeParameters|.R|kotlin/collections/zip|<R|IrTypeParameter|, R|IrTypeParameter|>(R|<local>/other|.R|/IrTypeParametersContainer.typeParameters|).R|SubstitutionOverride<kotlin/collections/List.iterator: R|kotlin/collections/Iterator<kotlin/Pair<IrTypeParameter, IrTypeParameter>>|>|()
while(R|<local>/<iterator>|.R|kotlin/collections/Iterator.hasNext|()) {
while(R|<local>/<iterator>|.R|SubstitutionOverride<kotlin/collections/Iterator.hasNext: R|kotlin/Boolean|>|()) {
lval <destruct>: R|kotlin/Pair<IrTypeParameter, IrTypeParameter>| = R|<local>/<iterator>|.R|SubstitutionOverride<kotlin/collections/Iterator.next: R|kotlin/Pair<IrTypeParameter, IrTypeParameter>|>|()
lval thisTypeParameter: R|IrTypeParameter| = R|<local>/<destruct>|.R|SubstitutionOverride<kotlin/Pair.component1: R|IrTypeParameter|>|()
lval otherTypeParameter: R|IrTypeParameter| = R|<local>/<destruct>|.R|SubstitutionOverride<kotlin/Pair.component2: R|IrTypeParameter|>|()
@@ -46,10 +46,10 @@ FILE: valueOfOrNull.kt
public final inline fun <reified E : R|kotlin/Enum<E>|> valueOfOrNull(value: R|kotlin/String|): R|E?| {
{
lval <iterator>: R|kotlin/collections/Iterator<E>| = R|kotlin/enumValues|<R|E|>().R|SubstitutionOverride<kotlin/Array.iterator: R|kotlin/collections/Iterator<E>|>|()
while(R|<local>/<iterator>|.R|kotlin/collections/Iterator.hasNext|()) {
while(R|<local>/<iterator>|.R|SubstitutionOverride<kotlin/collections/Iterator.hasNext: R|kotlin/Boolean|>|()) {
lval enumValue: R|E| = R|<local>/<iterator>|.R|SubstitutionOverride<kotlin/collections/Iterator.next: R|E|>|()
when () {
==(R|<local>/enumValue|.R|kotlin/Enum.name|, R|<local>/value|) -> {
==(R|<local>/enumValue|.R|SubstitutionOverride<kotlin/Enum.name: R|kotlin/String|>|, R|<local>/value|) -> {
^valueOfOrNull R|<local>/enumValue|
}
}