FIR: skip return insertion for lambda w/ Unit return type

This commit is contained in:
Jinseong Jeon
2020-08-20 23:41:09 -07:00
committed by Mikhail Glukhikh
parent f1ce668ede
commit ca541337d1
27 changed files with 52 additions and 55 deletions
@@ -60,7 +60,7 @@ FILE: RedundantReturnUnitTypeChecker.kt
public final fun foo(): R|kotlin/Unit| { public final fun foo(): R|kotlin/Unit| {
^foo this@R|/B|.R|/B.run|<R|kotlin/Int|>(<L> = run@fun <anonymous>(): R|kotlin/Int| { ^foo this@R|/B|.R|/B.run|<R|kotlin/Int|>(<L> = run@fun <anonymous>(): R|kotlin/Int| {
^ this@R|/B|.R|/B.bar|() this@R|/B|.R|/B.bar|()
} }
) )
} }
@@ -89,7 +89,7 @@ FILE: RedundantReturnUnitTypeChecker.kt
public final fun goo(): R|kotlin/Unit| { public final fun goo(): R|kotlin/Unit| {
^goo (this@R|/B|, Int(1)).R|/B.let|<R|kotlin/Int|, R|kotlin/Int|>(<L> = let@fun <anonymous>(it: R|kotlin/Int|): R|kotlin/Int| { ^goo (this@R|/B|, Int(1)).R|/B.let|<R|kotlin/Int|, R|kotlin/Int|>(<L> = let@fun <anonymous>(it: R|kotlin/Int|): R|kotlin/Int| {
^ this@R|/B|.R|/B.bar|() this@R|/B|.R|/B.bar|()
} }
) )
} }
@@ -6,7 +6,7 @@ FILE: lambdas.kt
when () { when () {
(R|<local>/x| is R|kotlin/Int|) -> { (R|<local>/x| is R|kotlin/Int|) -> {
R|/run|(<L> = run@fun <anonymous>(): R|kotlin/Unit| <kind=UNKNOWN> { R|/run|(<L> = run@fun <anonymous>(): R|kotlin/Unit| <kind=UNKNOWN> {
^ R|<local>/x|.R|kotlin/Int.inc|() R|<local>/x|.R|kotlin/Int.inc|()
} }
) )
} }
@@ -9,7 +9,7 @@ FILE: lambda.kt
} }
public final fun main(): R|kotlin/Unit| { public final fun main(): R|kotlin/Unit| {
R|/foo|(<L> = foo@fun <anonymous>(): R|kotlin/Unit| { R|/foo|(<L> = foo@fun <anonymous>(): R|kotlin/Unit| {
^ String(This is test) String(This is test)
} }
) )
R|/bar|(<L> = bar@fun <anonymous>(): R|kotlin/String| { R|/bar|(<L> = bar@fun <anonymous>(): R|kotlin/String| {
@@ -35,7 +35,7 @@ FILE: lambdaWithReceiver.kt
R|/complexLambda|(<L> = complexLambda@fun R|kotlin/Int|.<anonymous>(it: R|kotlin/String|): R|kotlin/Unit| { R|/complexLambda|(<L> = complexLambda@fun R|kotlin/Int|.<anonymous>(it: R|kotlin/String|): R|kotlin/Unit| {
this@R|special/anonymous|.R|kotlin/Int.inc|() this@R|special/anonymous|.R|kotlin/Int.inc|()
this@R|special/anonymous|.R|kotlin/Int.inc|() this@R|special/anonymous|.R|kotlin/Int.inc|()
^ R|<local>/it|.R|kotlin/String.length| R|<local>/it|.R|kotlin/String.length|
} }
) )
} }
@@ -9,13 +9,13 @@ FILE: lambdaInElvis.kt
} }
public final fun bar1(w: R|kotlin/collections/List<kotlin/CharSequence>|): R|kotlin/collections/List<kotlin/CharSequence>?| { public final fun bar1(w: R|kotlin/collections/List<kotlin/CharSequence>|): R|kotlin/collections/List<kotlin/CharSequence>?| {
^bar1 R|/foo|<R|kotlin/CharSequence|>(<L> = foo@fun <anonymous>(container: R|kotlin/collections/MutableList<kotlin/CharSequence>|): R|kotlin/Unit| { ^bar1 R|/foo|<R|kotlin/CharSequence|>(<L> = foo@fun <anonymous>(container: R|kotlin/collections/MutableList<kotlin/CharSequence>|): R|kotlin/Unit| {
^ R|<local>/container|.R|FakeOverride<kotlin/collections/MutableList.add: R|kotlin/Boolean|>|(String()) R|<local>/container|.R|FakeOverride<kotlin/collections/MutableList.add: R|kotlin/Boolean|>|(String())
} }
) ?: R|<local>/w| ) ?: R|<local>/w|
} }
public final fun bar2(): R|kotlin/collections/List<kotlin/CharSequence>?| { public final fun bar2(): R|kotlin/collections/List<kotlin/CharSequence>?| {
^bar2 R|/foo|<R|kotlin/CharSequence|>(<L> = foo@fun <anonymous>(container: R|kotlin/collections/MutableList<kotlin/CharSequence>|): R|kotlin/Unit| { ^bar2 R|/foo|<R|kotlin/CharSequence|>(<L> = foo@fun <anonymous>(container: R|kotlin/collections/MutableList<kotlin/CharSequence>|): R|kotlin/Unit| {
^ R|<local>/container|.R|FakeOverride<kotlin/collections/MutableList.add: R|kotlin/Boolean|>|(String()) R|<local>/container|.R|FakeOverride<kotlin/collections/MutableList.add: R|kotlin/Boolean|>|(String())
} }
) ?: R|/listOf|<R|kotlin/CharSequence|>() ) ?: R|/listOf|<R|kotlin/CharSequence|>()
} }
@@ -7,7 +7,7 @@ FILE: complexLambdaWithTypeVariableAsExpectedType.kt
} }
public final fun test(): R|kotlin/Unit| { public final fun test(): R|kotlin/Unit| {
R|/select|<R|(kotlin/Int) -> kotlin/Unit|>(R|/id|<R|(kotlin/Int) -> kotlin/Int|>(<L> = id@fun <anonymous>(it: R|kotlin/Int|): R|kotlin/Int| { R|/select|<R|(kotlin/Int) -> kotlin/Unit|>(R|/id|<R|(kotlin/Int) -> kotlin/Int|>(<L> = id@fun <anonymous>(it: R|kotlin/Int|): R|kotlin/Int| {
^ R|<local>/it|.R|kotlin/Int.inv|() R|<local>/it|.R|kotlin/Int.inv|()
} }
), R|/id|<R|(kotlin/Int) -> kotlin/Unit|>(<L> = id@fun <anonymous>(it: R|kotlin/Int|): R|kotlin/Unit| { ), R|/id|<R|(kotlin/Int) -> kotlin/Unit|>(<L> = id@fun <anonymous>(it: R|kotlin/Int|): R|kotlin/Unit| {
^@id Unit ^@id Unit
@@ -1,11 +1,11 @@
FILE: main.kt FILE: main.kt
public final fun main(): R|kotlin/Unit| { public final fun main(): R|kotlin/Unit| {
Q|JavaClass|.R|/JavaClass.foo|(<L> = foo@fun <anonymous>(): R|kotlin/Unit| { Q|JavaClass|.R|/JavaClass.foo|(<L> = foo@fun <anonymous>(): R|kotlin/Unit| {
^ String() String()
} }
) )
R|/JavaClass.JavaClass|().R|/JavaClass.bar|(<L> = bar@fun <anonymous>(): R|kotlin/Unit| { R|/JavaClass.JavaClass|().R|/JavaClass.bar|(<L> = bar@fun <anonymous>(): R|kotlin/Unit| {
^ String() String()
} }
) )
} }
@@ -21,7 +21,7 @@ FILE: safeCalls.kt
} }
public final fun test_3(x: R|kotlin/Any|): R|kotlin/Unit| { public final fun test_3(x: R|kotlin/Any|): R|kotlin/Unit| {
(R|<local>/x| as? R|A|)?.{ $subj$.R|/A.bar|(R|<local>/x|) }?.{ $subj$.R|/foo|(R|<local>/x|.R|/A.bool|()) }?.{ $subj$.R|/let|(<L> = let@fun <anonymous>(): R|kotlin/Unit| { (R|<local>/x| as? R|A|)?.{ $subj$.R|/A.bar|(R|<local>/x|) }?.{ $subj$.R|/foo|(R|<local>/x|.R|/A.bool|()) }?.{ $subj$.R|/let|(<L> = let@fun <anonymous>(): R|kotlin/Unit| {
^ R|<local>/x|.R|/A.bool|() R|<local>/x|.R|/A.bool|()
} }
) } ) }
R|<local>/x|.<Unresolved name: bool>#() R|<local>/x|.<Unresolved name: bool>#()
@@ -2,7 +2,7 @@ FILE: addAllOnJavaCollection.kt
public final fun foo(): R|kotlin/Unit| { public final fun foo(): R|kotlin/Unit| {
lval y: R|kotlin/collections/List<kotlin/String>| = R|kotlin/collections/listOf|<R|kotlin/String|>(vararg(String(Alpha), String(Beta))) lval y: R|kotlin/collections/List<kotlin/String>| = R|kotlin/collections/listOf|<R|kotlin/String|>(vararg(String(Alpha), String(Beta)))
lval x: R|java/util/LinkedHashSet<kotlin/String>| = R|java/util/LinkedHashSet.LinkedHashSet|<R|kotlin/String|>().R|kotlin/apply|<R|java/util/LinkedHashSet<kotlin/String>|>(<L> = apply@fun R|java/util/LinkedHashSet<kotlin/String>|.<anonymous>(): R|kotlin/Unit| <kind=EXACTLY_ONCE> { lval x: R|java/util/LinkedHashSet<kotlin/String>| = R|java/util/LinkedHashSet.LinkedHashSet|<R|kotlin/String|>().R|kotlin/apply|<R|java/util/LinkedHashSet<kotlin/String>|>(<L> = apply@fun R|java/util/LinkedHashSet<kotlin/String>|.<anonymous>(): R|kotlin/Unit| <kind=EXACTLY_ONCE> {
^ this@R|special/anonymous|.R|FakeOverride<java/util/LinkedHashSet.addAll: R|kotlin/Boolean|>|(R|<local>/y|) this@R|special/anonymous|.R|FakeOverride<java/util/LinkedHashSet.addAll: R|kotlin/Boolean|>|(R|<local>/y|)
} }
) )
lval z: R|java/util/ArrayList<kotlin/String>| = R|java/util/ArrayList.ArrayList|<R|kotlin/String|>() lval z: R|java/util/ArrayList<kotlin/String>| = R|java/util/ArrayList.ArrayList|<R|kotlin/String|>()
@@ -7,9 +7,9 @@ FILE: complexPostponedCfg.kt
lval firstCalls: R|kotlin/collections/List<FirFunctionCall>| = R|kotlin/with|<R|FirFunctionCall|, R|kotlin/collections/List<FirFunctionCall>|>((R|<local>/statements|.R|kotlin/collections/last|<R|FirBase|>() as R|FirFunctionCall|), <L> = setCall@fun R|FirFunctionCall|.<anonymous>(): R|kotlin/collections/List<FirFunctionCall>| <kind=EXACTLY_ONCE> { lval firstCalls: R|kotlin/collections/List<FirFunctionCall>| = R|kotlin/with|<R|FirFunctionCall|, R|kotlin/collections/List<FirFunctionCall>|>((R|<local>/statements|.R|kotlin/collections/last|<R|FirBase|>() as R|FirFunctionCall|), <L> = setCall@fun R|FirFunctionCall|.<anonymous>(): R|kotlin/collections/List<FirFunctionCall>| <kind=EXACTLY_ONCE> {
^ R|kotlin/collections/buildList|<R|FirFunctionCall|>(<L> = buildList@fun R|kotlin/collections/MutableList<FirFunctionCall>|.<anonymous>(): R|kotlin/Unit| <kind=EXACTLY_ONCE> { ^ R|kotlin/collections/buildList|<R|FirFunctionCall|>(<L> = buildList@fun R|kotlin/collections/MutableList<FirFunctionCall>|.<anonymous>(): R|kotlin/Unit| <kind=EXACTLY_ONCE> {
this@R|special/anonymous|.R|FakeOverride<kotlin/collections/MutableList.add: R|kotlin/Boolean|>|(this@R|special/anonymous|) this@R|special/anonymous|.R|FakeOverride<kotlin/collections/MutableList.add: R|kotlin/Boolean|>|(this@R|special/anonymous|)
^ R|kotlin/with|<R|FirFunctionCall|, R|kotlin/Boolean|>((R|<local>/arguments|.R|kotlin/collections/last|<R|FirBase|>() as R|FirFunctionCall|), <L> = plusCall@fun R|FirFunctionCall|.<anonymous>(): R|kotlin/Boolean| <kind=EXACTLY_ONCE> { R|kotlin/with|<R|FirFunctionCall|, R|kotlin/Boolean|>((R|<local>/arguments|.R|kotlin/collections/last|<R|FirBase|>() as R|FirFunctionCall|), <L> = plusCall@fun R|FirFunctionCall|.<anonymous>(): R|kotlin/Boolean| <kind=EXACTLY_ONCE> {
this@R|special/anonymous|.R|FakeOverride<kotlin/collections/MutableList.add: R|kotlin/Boolean|>|(this@R|special/anonymous|) this@R|special/anonymous|.R|FakeOverride<kotlin/collections/MutableList.add: R|kotlin/Boolean|>|(this@R|special/anonymous|)
^ this@R|special/anonymous|.R|FakeOverride<kotlin/collections/MutableList.add: R|kotlin/Boolean|>|((R|<local>/explicitReceiver| as R|FirFunctionCall|)) this@R|special/anonymous|.R|FakeOverride<kotlin/collections/MutableList.add: R|kotlin/Boolean|>|((R|<local>/explicitReceiver| as R|FirFunctionCall|))
} }
) )
} }
@@ -9,13 +9,13 @@ FILE: callsInPlace.kt
} }
public final fun test_2(): R|kotlin/Unit| { public final fun test_2(): R|kotlin/Unit| {
R|kotlin/repeat|(Int(10), <L> = repeat@fun <anonymous>(it: R|kotlin/Int|): R|kotlin/Unit| <kind=UNKNOWN> { R|kotlin/repeat|(Int(10), <L> = repeat@fun <anonymous>(it: R|kotlin/Int|): R|kotlin/Unit| <kind=UNKNOWN> {
^ String(test_2) String(test_2)
} }
) )
} }
public final fun test_3(): R|kotlin/Unit| { public final fun test_3(): R|kotlin/Unit| {
R|kotlin/repeat|(action = repeat@fun <anonymous>(it: R|kotlin/Int|): R|kotlin/Unit| <kind=UNKNOWN> { R|kotlin/repeat|(action = repeat@fun <anonymous>(it: R|kotlin/Int|): R|kotlin/Unit| <kind=UNKNOWN> {
^ String(test_3) String(test_3)
} }
, times = Int(10)) , times = Int(10))
} }
@@ -39,19 +39,19 @@ FILE: callsInPlace.kt
} }
public final fun test_6(): R|kotlin/Unit| { public final fun test_6(): R|kotlin/Unit| {
R|/myRun|(myRun@fun <anonymous>(): R|kotlin/Unit| <kind=UNKNOWN> { R|/myRun|(myRun@fun <anonymous>(): R|kotlin/Unit| <kind=UNKNOWN> {
^ String(test_6_1) String(test_6_1)
} }
, <L> = myRun@fun <anonymous>(): R|kotlin/Unit| <kind=UNKNOWN> { , <L> = myRun@fun <anonymous>(): R|kotlin/Unit| <kind=UNKNOWN> {
^ String(test_6_2) String(test_6_2)
} }
) )
} }
public final fun test_7(): R|kotlin/Unit| { public final fun test_7(): R|kotlin/Unit| {
R|/myRun|(block2 = myRun@fun <anonymous>(): R|kotlin/Unit| <kind=UNKNOWN> { R|/myRun|(block2 = myRun@fun <anonymous>(): R|kotlin/Unit| <kind=UNKNOWN> {
^ String(test_7_2) String(test_7_2)
} }
, block1 = myRun@fun <anonymous>(): R|kotlin/Unit| <kind=UNKNOWN> { , block1 = myRun@fun <anonymous>(): R|kotlin/Unit| <kind=UNKNOWN> {
^ String(test_7_1) String(test_7_1)
} }
) )
} }
@@ -60,7 +60,7 @@ FILE: callsInPlace.kt
} }
public final fun test_8(): R|kotlin/Unit| { public final fun test_8(): R|kotlin/Unit| {
R|/myDummyRun|(<L> = myDummyRun@fun <anonymous>(): R|kotlin/Unit| { R|/myDummyRun|(<L> = myDummyRun@fun <anonymous>(): R|kotlin/Unit| {
^ String(test_8) String(test_8)
} }
) )
} }
@@ -15,7 +15,7 @@ FILE: hashTableWithForEach.kt
R|/DEBUG| -> { R|/DEBUG| -> {
^ Q|java/util/Collections|.R|java/util/Collections.unmodifiableSet|<R|ft<kotlin/collections/MutableMap.MutableEntry<K, V>, kotlin/collections/MutableMap.MutableEntry<K, V>?>!|>(R|kotlin/collections/mutableSetOf|<R|kotlin/collections/MutableMap.MutableEntry<K, V>|>().R|kotlin/apply|<R|kotlin/collections/MutableSet<kotlin/collections/MutableMap.MutableEntry<K, V>>|>(<L> = apply@fun R|kotlin/collections/MutableSet<kotlin/collections/MutableMap.MutableEntry<K, V>>|.<anonymous>(): R|kotlin/Unit| <kind=EXACTLY_ONCE> { ^ Q|java/util/Collections|.R|java/util/Collections.unmodifiableSet|<R|ft<kotlin/collections/MutableMap.MutableEntry<K, V>, kotlin/collections/MutableMap.MutableEntry<K, V>?>!|>(R|kotlin/collections/mutableSetOf|<R|kotlin/collections/MutableMap.MutableEntry<K, V>|>().R|kotlin/apply|<R|kotlin/collections/MutableSet<kotlin/collections/MutableMap.MutableEntry<K, V>>|>(<L> = apply@fun R|kotlin/collections/MutableSet<kotlin/collections/MutableMap.MutableEntry<K, V>>|.<anonymous>(): R|kotlin/Unit| <kind=EXACTLY_ONCE> {
this@R|/SomeHashTable|.R|/SomeHashTable.forEach|(<L> = forEach@fun <anonymous>(key: R|K|, value: R|V|): R|kotlin/Unit| { this@R|/SomeHashTable|.R|/SomeHashTable.forEach|(<L> = forEach@fun <anonymous>(key: R|K|, value: R|V|): R|kotlin/Unit| {
^ this@R|special/anonymous|.R|FakeOverride<kotlin/collections/MutableSet.add: R|kotlin/Boolean|>|(R|/SomeHashTable.Entry.Entry|<R|K|, R|V|>(R|<local>/key|, R|<local>/value|)) this@R|special/anonymous|.R|FakeOverride<kotlin/collections/MutableSet.add: R|kotlin/Boolean|>|(R|/SomeHashTable.Entry.Entry|<R|K|, R|V|>(R|<local>/key|, R|<local>/value|))
} }
) )
} }
@@ -6,7 +6,7 @@ FILE: builderInference.kt
} }
public final fun test(): R|kotlin/Unit| { public final fun test(): R|kotlin/Unit| {
lval s: R|kotlin/String| = R|/foo|<R|kotlin/String|>(<L> = foo@fun R|kotlin/collections/MutableList<kotlin/String>|.<anonymous>(): R|kotlin/Unit| { lval s: R|kotlin/String| = R|/foo|<R|kotlin/String|>(<L> = foo@fun R|kotlin/collections/MutableList<kotlin/String>|.<anonymous>(): R|kotlin/Unit| {
^ this@R|special/anonymous|.R|FakeOverride<kotlin/collections/MutableList.add: R|kotlin/Boolean|>|(String()) this@R|special/anonymous|.R|FakeOverride<kotlin/collections/MutableList.add: R|kotlin/Boolean|>|(String())
} }
) )
R|/takeString|(R|<local>/s|) R|/takeString|(R|<local>/s|)
@@ -1,14 +1,14 @@
FILE: builderInferenceFromStdlib.kt FILE: builderInferenceFromStdlib.kt
public final fun test_1(): R|kotlin/Unit| { public final fun test_1(): R|kotlin/Unit| {
lval list: R|kotlin/collections/List<kotlin/String>| = R|kotlin/collections/buildList|<R|kotlin/String|>(<L> = buildList@fun R|kotlin/collections/MutableList<kotlin/String>|.<anonymous>(): R|kotlin/Unit| <kind=EXACTLY_ONCE> { lval list: R|kotlin/collections/List<kotlin/String>| = R|kotlin/collections/buildList|<R|kotlin/String|>(<L> = buildList@fun R|kotlin/collections/MutableList<kotlin/String>|.<anonymous>(): R|kotlin/Unit| <kind=EXACTLY_ONCE> {
^ this@R|special/anonymous|.R|FakeOverride<kotlin/collections/MutableList.add: R|kotlin/Boolean|>|(String()) this@R|special/anonymous|.R|FakeOverride<kotlin/collections/MutableList.add: R|kotlin/Boolean|>|(String())
} }
) )
R|/takeList|(R|<local>/list|) R|/takeList|(R|<local>/list|)
} }
public final fun test_2(): R|kotlin/Unit| { public final fun test_2(): R|kotlin/Unit| {
lval list: R|kotlin/collections/List<kotlin/String>| = R|/myBuildList|<R|kotlin/String|>(<L> = myBuildList@fun R|kotlin/collections/MutableList<kotlin/String>|.<anonymous>(): R|kotlin/Unit| { lval list: R|kotlin/collections/List<kotlin/String>| = R|/myBuildList|<R|kotlin/String|>(<L> = myBuildList@fun R|kotlin/collections/MutableList<kotlin/String>|.<anonymous>(): R|kotlin/Unit| {
^ this@R|special/anonymous|.R|FakeOverride<kotlin/collections/MutableList.add: R|kotlin/Boolean|>|(String()) this@R|special/anonymous|.R|FakeOverride<kotlin/collections/MutableList.add: R|kotlin/Boolean|>|(String())
} }
) )
R|/takeList|(R|<local>/list|) R|/takeList|(R|<local>/list|)
@@ -9,7 +9,7 @@ FILE: test.kt
R|<local>/map|.R|FakeOverride</MyMap.forEach: R|kotlin/Unit|>|(<L> = forEach@fun <anonymous>(key: R|ft<kotlin/String, kotlin/String?>!|, value: R|ft<kotlin/String, kotlin/String?>!|): R|kotlin/Unit| { R|<local>/map|.R|FakeOverride</MyMap.forEach: R|kotlin/Unit|>|(<L> = forEach@fun <anonymous>(key: R|ft<kotlin/String, kotlin/String?>!|, value: R|ft<kotlin/String, kotlin/String?>!|): R|kotlin/Unit| {
R|kotlin/io/println|(<strcat>(R|<local>/key|.R|kotlin/Any.toString|(), String(: ), R|<local>/value|.R|kotlin/Any.toString|())) R|kotlin/io/println|(<strcat>(R|<local>/key|.R|kotlin/Any.toString|(), String(: ), R|<local>/value|.R|kotlin/Any.toString|()))
R|<local>/key|.R|kotlin/String.length| R|<local>/key|.R|kotlin/String.length|
^ R|<local>/value|.R|kotlin/String.length| R|<local>/value|.R|kotlin/String.length|
} }
) )
R|<local>/map|.R|kotlin/collections/forEach|<R|ft<kotlin/String, kotlin/String?>!|, R|ft<kotlin/String, kotlin/String?>!|>(<L> = forEach@fun <anonymous>(<destruct>: R|kotlin/collections/Map.Entry<ft<kotlin/String, kotlin/String?>!, ft<kotlin/String, kotlin/String?>!>|): R|kotlin/Unit| <kind=UNKNOWN> { R|<local>/map|.R|kotlin/collections/forEach|<R|ft<kotlin/String, kotlin/String?>!|, R|ft<kotlin/String, kotlin/String?>!|>(<L> = forEach@fun <anonymous>(<destruct>: R|kotlin/collections/Map.Entry<ft<kotlin/String, kotlin/String?>!, ft<kotlin/String, kotlin/String?>!>|): R|kotlin/Unit| <kind=UNKNOWN> {
@@ -17,7 +17,7 @@ FILE: test.kt
lval value: R|ft<kotlin/String, kotlin/String?>!| = R|<local>/<destruct>|.R|kotlin/collections/component2|<R|ft<kotlin/String, kotlin/String?>!|, R|ft<kotlin/String, kotlin/String?>!|>() lval value: R|ft<kotlin/String, kotlin/String?>!| = R|<local>/<destruct>|.R|kotlin/collections/component2|<R|ft<kotlin/String, kotlin/String?>!|, R|ft<kotlin/String, kotlin/String?>!|>()
R|kotlin/io/println|(<strcat>(R|<local>/key|.R|kotlin/Any.toString|(), String(: ), R|<local>/value|.R|kotlin/Any.toString|())) R|kotlin/io/println|(<strcat>(R|<local>/key|.R|kotlin/Any.toString|(), String(: ), R|<local>/value|.R|kotlin/Any.toString|()))
R|<local>/key|.R|kotlin/String.length| R|<local>/key|.R|kotlin/String.length|
^ R|<local>/value|.R|kotlin/String.length| R|<local>/value|.R|kotlin/String.length|
} }
) )
} }
@@ -31,7 +31,7 @@ FILE: test.kt
R|<local>/map|.R|FakeOverride<kotlin/collections/MutableMap.forEach: R|kotlin/Unit|>|(<L> = forEach@fun <anonymous>(key: R|ft<kotlin/String, kotlin/String?>!|, value: R|ft<kotlin/String, kotlin/String?>!|): R|kotlin/Unit| { R|<local>/map|.R|FakeOverride<kotlin/collections/MutableMap.forEach: R|kotlin/Unit|>|(<L> = forEach@fun <anonymous>(key: R|ft<kotlin/String, kotlin/String?>!|, value: R|ft<kotlin/String, kotlin/String?>!|): R|kotlin/Unit| {
R|kotlin/io/println|(<strcat>(R|<local>/key|.R|kotlin/Any.toString|(), String(: ), R|<local>/value|.R|kotlin/Any.toString|())) R|kotlin/io/println|(<strcat>(R|<local>/key|.R|kotlin/Any.toString|(), String(: ), R|<local>/value|.R|kotlin/Any.toString|()))
R|<local>/key|.R|kotlin/String.length| R|<local>/key|.R|kotlin/String.length|
^ R|<local>/value|.R|kotlin/String.length| R|<local>/value|.R|kotlin/String.length|
} }
) )
R|<local>/map|.R|kotlin/collections/forEach|<R|kotlin/String|, R|kotlin/String|>(<L> = forEach@fun <anonymous>(<destruct>: R|kotlin/collections/Map.Entry<kotlin/String, kotlin/String>|): R|kotlin/Unit| <kind=UNKNOWN> { R|<local>/map|.R|kotlin/collections/forEach|<R|kotlin/String|, R|kotlin/String|>(<L> = forEach@fun <anonymous>(<destruct>: R|kotlin/collections/Map.Entry<kotlin/String, kotlin/String>|): R|kotlin/Unit| <kind=UNKNOWN> {
@@ -39,7 +39,7 @@ FILE: test.kt
lval value: R|kotlin/String| = R|<local>/<destruct>|.R|kotlin/collections/component2|<R|kotlin/String|, R|kotlin/String|>() lval value: R|kotlin/String| = R|<local>/<destruct>|.R|kotlin/collections/component2|<R|kotlin/String|, R|kotlin/String|>()
R|kotlin/io/println|(<strcat>(R|<local>/key|.R|kotlin/Any.toString|(), String(: ), R|<local>/value|.R|kotlin/Any.toString|())) R|kotlin/io/println|(<strcat>(R|<local>/key|.R|kotlin/Any.toString|(), String(: ), R|<local>/value|.R|kotlin/Any.toString|()))
R|<local>/key|.R|kotlin/String.length| R|<local>/key|.R|kotlin/String.length|
^ R|<local>/value|.R|kotlin/String.length| R|<local>/value|.R|kotlin/String.length|
} }
) )
} }
@@ -2,12 +2,12 @@ FILE: test.kt
public final fun <D : R|kotlin/Any|> R|Call<D>|.testForEach(): R|kotlin/Unit| { public final fun <D : R|kotlin/Any|> R|Call<D>|.testForEach(): R|kotlin/Unit| {
this@R|/testForEach|.R|/Call.arguments|.R|FakeOverride<kotlin/collections/MutableMap.forEach: R|kotlin/Unit|>|(<L> = forEach@fun <anonymous>(key: R|ft<kotlin/String, kotlin/String?>!|, value: R|ft<kotlin/String, kotlin/String?>!|): R|kotlin/Unit| { this@R|/testForEach|.R|/Call.arguments|.R|FakeOverride<kotlin/collections/MutableMap.forEach: R|kotlin/Unit|>|(<L> = forEach@fun <anonymous>(key: R|ft<kotlin/String, kotlin/String?>!|, value: R|ft<kotlin/String, kotlin/String?>!|): R|kotlin/Unit| {
R|<local>/key|.R|kotlin/String.length| R|<local>/key|.R|kotlin/String.length|
^ R|<local>/value|.R|kotlin/String.length| R|<local>/value|.R|kotlin/String.length|
} }
) )
this@R|/testForEach|.R|/Call.arguments|.R|kotlin/collections/forEach|<R|ft<kotlin/String, kotlin/String?>!|, R|ft<kotlin/String, kotlin/String?>!|>(<L> = forEach@fun <anonymous>(it: R|kotlin/collections/Map.Entry<ft<kotlin/String, kotlin/String?>!, ft<kotlin/String, kotlin/String?>!>|): R|kotlin/Unit| <kind=UNKNOWN> { this@R|/testForEach|.R|/Call.arguments|.R|kotlin/collections/forEach|<R|ft<kotlin/String, kotlin/String?>!|, R|ft<kotlin/String, kotlin/String?>!|>(<L> = forEach@fun <anonymous>(it: R|kotlin/collections/Map.Entry<ft<kotlin/String, kotlin/String?>!, ft<kotlin/String, kotlin/String?>!>|): R|kotlin/Unit| <kind=UNKNOWN> {
R|<local>/it|.R|FakeOverride<kotlin/collections/Map.Entry.key: R|ft<kotlin/String, kotlin/String?>!|>|.R|kotlin/String.length| R|<local>/it|.R|FakeOverride<kotlin/collections/Map.Entry.key: R|ft<kotlin/String, kotlin/String?>!|>|.R|kotlin/String.length|
^ R|<local>/it|.R|FakeOverride<kotlin/collections/Map.Entry.value: R|ft<kotlin/String, kotlin/String?>!|>|.R|kotlin/String.length| R|<local>/it|.R|FakeOverride<kotlin/collections/Map.Entry.value: R|ft<kotlin/String, kotlin/String?>!|>|.R|kotlin/String.length|
} }
) )
} }
@@ -7,7 +7,7 @@ FILE: mapList.kt
) )
R|<local>/u|.R|/applyX|<R|kotlin/collections/List<kotlin/Int>|>(<L> = applyX@fun R|kotlin/collections/List<kotlin/Int>|.<anonymous>(): R|kotlin/Unit| <kind=UNKNOWN> { R|<local>/u|.R|/applyX|<R|kotlin/collections/List<kotlin/Int>|>(<L> = applyX@fun R|kotlin/collections/List<kotlin/Int>|.<anonymous>(): R|kotlin/Unit| <kind=UNKNOWN> {
this@R|special/anonymous|.R|FakeOverride<kotlin/collections/List.contains: R|kotlin/Boolean|>|(Int(1)) this@R|special/anonymous|.R|FakeOverride<kotlin/collections/List.contains: R|kotlin/Boolean|>|(Int(1))
^ this@R|special/anonymous|.R|FakeOverride<kotlin/collections/List.contains: R|kotlin/Boolean|>|(Int(1)) this@R|special/anonymous|.R|FakeOverride<kotlin/collections/List.contains: R|kotlin/Boolean|>|(Int(1))
} }
) )
} }
@@ -11,7 +11,7 @@ FILE: noneWithForEach.kt
} }
).R|kotlin/collections/forEach|<R|kotlin/String|, R|kotlin/collections/List<Diagnostic>|>(<L> = forEach@fun <anonymous>(it: R|kotlin/collections/Map.Entry<kotlin/String, kotlin/collections/List<Diagnostic>>|): R|kotlin/Unit| <kind=UNKNOWN> { ).R|kotlin/collections/forEach|<R|kotlin/String|, R|kotlin/collections/List<Diagnostic>|>(<L> = forEach@fun <anonymous>(it: R|kotlin/collections/Map.Entry<kotlin/String, kotlin/collections/List<Diagnostic>>|): R|kotlin/Unit| <kind=UNKNOWN> {
lval diagnostics: R|kotlin/collections/List<Diagnostic>| = R|<local>/it|.R|FakeOverride<kotlin/collections/Map.Entry.value: R|kotlin/collections/List<Diagnostic>|>| lval diagnostics: R|kotlin/collections/List<Diagnostic>| = R|<local>/it|.R|FakeOverride<kotlin/collections/Map.Entry.value: R|kotlin/collections/List<Diagnostic>|>|
^ R|<local>/filtered|.R|FakeOverride<java/util/ArrayList.addAll: R|kotlin/Boolean|>|(R|<local>/diagnostics|.R|kotlin/collections/filter|<R|Diagnostic|>(<L> = filter@fun <anonymous>(me: R|Diagnostic|): R|kotlin/Boolean| <kind=UNKNOWN> { R|<local>/filtered|.R|FakeOverride<java/util/ArrayList.addAll: R|kotlin/Boolean|>|(R|<local>/diagnostics|.R|kotlin/collections/filter|<R|Diagnostic|>(<L> = filter@fun <anonymous>(me: R|Diagnostic|): R|kotlin/Boolean| <kind=UNKNOWN> {
^ R|<local>/diagnostics|.R|kotlin/collections/none|<R|Diagnostic|>(<L> = none@fun <anonymous>(other: R|Diagnostic|): R|kotlin/Boolean| <kind=UNKNOWN> { ^ R|<local>/diagnostics|.R|kotlin/collections/none|<R|Diagnostic|>(<L> = none@fun <anonymous>(other: R|Diagnostic|): R|kotlin/Boolean| <kind=UNKNOWN> {
^ !=(R|<local>/me|, R|<local>/other|) ^ !=(R|<local>/me|, R|<local>/other|)
} }
@@ -748,6 +748,12 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor
} }
private fun FirAnonymousFunction.addReturn(): FirAnonymousFunction { private fun FirAnonymousFunction.addReturn(): FirAnonymousFunction {
// If this lambda's resolved, expected return type is Unit, we don't need an explicit return statement.
// During conversion (to backend IR), the last expression will be coerced to Unit if needed.
// As per KT-41005, we should not force coercion to Unit for nullable return type, though.
if (returnTypeRef.isUnit && body?.typeRef?.isMarkedNullable == false) {
return this
}
val lastStatement = body?.statements?.lastOrNull() val lastStatement = body?.statements?.lastOrNull()
val returnType = (body?.typeRef as? FirResolvedTypeRef) ?: return this val returnType = (body?.typeRef as? FirResolvedTypeRef) ?: return this
val returnNothing = returnType.isNothing || returnType.isUnit val returnNothing = returnType.isNothing || returnType.isUnit
@@ -35,15 +35,21 @@ val FirTypeRef.isArrayType: Boolean
isBuiltinType(StandardClassIds.Array, false) || isBuiltinType(StandardClassIds.Array, false) ||
StandardClassIds.primitiveArrayTypeByElementType.values.any { isBuiltinType(it, false) } StandardClassIds.primitiveArrayTypeByElementType.values.any { isBuiltinType(it, false) }
private fun FirTypeRef.isBuiltinType(classId: ClassId, isNullable: Boolean): Boolean { private val FirTypeRef.classLikeTypeOrNull: ConeClassLikeType?
val type = when (this) { get() = when (this) {
is FirImplicitBuiltinTypeRef -> type is FirImplicitBuiltinTypeRef -> type
is FirResolvedTypeRef -> type as? ConeClassLikeType ?: return false is FirResolvedTypeRef -> type as? ConeClassLikeType
else -> return false else -> null
} }
private fun FirTypeRef.isBuiltinType(classId: ClassId, isNullable: Boolean): Boolean {
val type = this.classLikeTypeOrNull ?: return false
return type.lookupTag.classId == classId && type.isNullable == isNullable return type.lookupTag.classId == classId && type.isNullable == isNullable
} }
val FirTypeRef.isMarkedNullable: Boolean?
get() = classLikeTypeOrNull?.isMarkedNullable
val FirFunctionTypeRef.parametersCount: Int val FirFunctionTypeRef.parametersCount: Int
get() = if (receiverTypeRef != null) get() = if (receiverTypeRef != null)
valueParameters.size + 1 valueParameters.size + 1
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// WITH_RUNTIME // WITH_RUNTIME
// WITH_COROUTINES // WITH_COROUTINES
// COMMON_COROUTINES_TEST // COMMON_COROUTINES_TEST
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// WITH_RUNTIME // WITH_RUNTIME
// WITH_COROUTINES // WITH_COROUTINES
// COMMON_COROUTINES_TEST // COMMON_COROUTINES_TEST
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// WITH_RUNTIME // WITH_RUNTIME
// WITH_COROUTINES // WITH_COROUTINES
// COMMON_COROUTINES_TEST // COMMON_COROUTINES_TEST
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// WITH_RUNTIME // WITH_RUNTIME
// WITH_COROUTINES // WITH_COROUTINES
// COMMON_COROUTINES_TEST // COMMON_COROUTINES_TEST
@@ -142,8 +142,8 @@ fun main() {
val x18: (C) -> Unit = select(id { <!DEBUG_INFO_EXPRESSION_TYPE("C")!>it<!> }, { <!DEBUG_INFO_EXPRESSION_TYPE("C")!>it<!> }, id<(B) -> Unit> { x -> x }) val x18: (C) -> Unit = select(id { <!DEBUG_INFO_EXPRESSION_TYPE("C")!>it<!> }, { <!DEBUG_INFO_EXPRESSION_TYPE("C")!>it<!> }, id<(B) -> Unit> { x -> x })
// Resolution of extension/non-extension functions combination // Resolution of extension/non-extension functions combination
val x19: String.() -> Unit = select(<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Function1<kotlin.String, kotlin.Unit>")!>id { <!DEBUG_INFO_EXPRESSION_TYPE("ERROR CLASS: Unresolved this@null"), DEBUG_INFO_EXPRESSION_TYPE("kotlin.Nothing")!>this<!> }<!>, <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Function1<kotlin.String, kotlin.Unit>")!>id(fun(x: String) {})<!>) val x19: String.() -> Unit = select(<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Function1<kotlin.String, kotlin.Unit>")!>id { <!DEBUG_INFO_EXPRESSION_TYPE("ERROR CLASS: Unresolved this@null"), DEBUG_INFO_EXPRESSION_TYPE("ERROR CLASS: Unresolved this@null")!>this<!> }<!>, <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Function1<kotlin.String, kotlin.Unit>")!>id(fun(x: String) {})<!>)
val x20: String.() -> Unit = select(<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Function1<kotlin.String, kotlin.Unit>")!>{ <!DEBUG_INFO_EXPRESSION_TYPE("ERROR CLASS: Unresolved this@null"), DEBUG_INFO_EXPRESSION_TYPE("kotlin.Nothing")!>this<!> }<!>, (fun(x: String) {})) val x20: String.() -> Unit = select(<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Function1<kotlin.String, kotlin.Unit>")!>{ <!DEBUG_INFO_EXPRESSION_TYPE("ERROR CLASS: Unresolved this@null"), DEBUG_INFO_EXPRESSION_TYPE("ERROR CLASS: Unresolved this@null")!>this<!> }<!>, (fun(x: String) {}))
val x21: String.() -> Unit = select(<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Function1<kotlin.String, kotlin.Unit>")!>id(fun(x: String) {})<!>, <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Function1<kotlin.String, kotlin.Unit>")!>id(fun(x: String) {})<!>) val x21: String.() -> Unit = select(<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Function1<kotlin.String, kotlin.Unit>")!>id(fun(x: String) {})<!>, <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Function1<kotlin.String, kotlin.Unit>")!>id(fun(x: String) {})<!>)
select(id<String.() -> Unit>(fun(x: String) {}), <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Function1<kotlin.String, kotlin.Unit>")!>id(fun(x: String) {})<!>) select(id<String.() -> Unit>(fun(x: String) {}), <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Function1<kotlin.String, kotlin.Unit>")!>id(fun(x: String) {})<!>)
select(<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Function2<kotlin.String, kotlin.String, kotlin.Unit>")!>id(fun String.(x: String) {})<!>, <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Function2<kotlin.String, kotlin.String, kotlin.Unit>")!>id(fun(x: String, y: String) {})<!>) select(<!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Function2<kotlin.String, kotlin.String, kotlin.Unit>")!>id(fun String.(x: String) {})<!>, <!DEBUG_INFO_EXPRESSION_TYPE("kotlin.Function2<kotlin.String, kotlin.String, kotlin.Unit>")!>id(fun(x: String, y: String) {})<!>)
@@ -1,12 +0,0 @@
FILE fqName:<root> fileName:/coercionToUnitInLambdaReturnValue.kt
FUN name:use visibility:public modality:FINAL <> (fn:kotlin.Function0<kotlin.Unit>) returnType:kotlin.Unit
VALUE_PARAMETER name:fn index:0 type:kotlin.Function0<kotlin.Unit>
BLOCK_BODY
FUN name:test visibility:public modality:FINAL <> () returnType:kotlin.Unit
BLOCK_BODY
CALL 'public final fun use (fn: kotlin.Function0<kotlin.Unit>): kotlin.Unit declared in <root>' type=kotlin.Unit origin=null
fn: FUN_EXPR type=kotlin.Function0<kotlin.Unit> origin=LAMBDA
FUN LOCAL_FUNCTION_FOR_LAMBDA name:<anonymous> visibility:local modality:FINAL <> () returnType:kotlin.Unit
BLOCK_BODY
RETURN type=kotlin.Nothing from='local final fun <anonymous> (): kotlin.Unit declared in <root>.test'
CONST Int type=kotlin.Int value=42
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// !LANGUAGE: +NewInference // !LANGUAGE: +NewInference
fun use(fn: () -> Unit) {} fun use(fn: () -> Unit) {}