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| {
^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| {
^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 () {
(R|<local>/x| is R|kotlin/Int|) -> {
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| {
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| {
@@ -35,7 +35,7 @@ FILE: lambdaWithReceiver.kt
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|()
^ 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>?| {
^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|
}
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| {
^ 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|>()
}
@@ -7,7 +7,7 @@ FILE: complexLambdaWithTypeVariableAsExpectedType.kt
}
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|<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| {
^@id Unit
@@ -1,11 +1,11 @@
FILE: main.kt
public final fun main(): 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| {
^ String()
String()
}
)
}
@@ -21,7 +21,7 @@ FILE: safeCalls.kt
}
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|.R|/A.bool|()
R|<local>/x|.R|/A.bool|()
}
) }
R|<local>/x|.<Unresolved name: bool>#()
@@ -2,7 +2,7 @@ FILE: addAllOnJavaCollection.kt
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 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|>()
@@ -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> {
^ 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|)
^ 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|>|((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| {
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| {
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))
}
@@ -39,19 +39,19 @@ FILE: callsInPlace.kt
}
public final fun test_6(): R|kotlin/Unit| {
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> {
^ String(test_6_2)
String(test_6_2)
}
)
}
public final fun test_7(): R|kotlin/Unit| {
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> {
^ String(test_7_1)
String(test_7_1)
}
)
}
@@ -60,7 +60,7 @@ FILE: callsInPlace.kt
}
public final fun test_8(): 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| -> {
^ 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|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| {
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|)
@@ -1,14 +1,14 @@
FILE: builderInferenceFromStdlib.kt
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> {
^ 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|)
}
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| {
^ 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|)
@@ -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|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>/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> {
@@ -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?>!|>()
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>/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|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>/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> {
@@ -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|>()
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>/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| {
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>/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> {
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> {
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> {
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>/me|, R|<local>/other|)
}
@@ -748,6 +748,12 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor
}
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 returnType = (body?.typeRef as? FirResolvedTypeRef) ?: return this
val returnNothing = returnType.isNothing || returnType.isUnit
@@ -35,15 +35,21 @@ val FirTypeRef.isArrayType: Boolean
isBuiltinType(StandardClassIds.Array, false) ||
StandardClassIds.primitiveArrayTypeByElementType.values.any { isBuiltinType(it, false) }
private fun FirTypeRef.isBuiltinType(classId: ClassId, isNullable: Boolean): Boolean {
val type = when (this) {
private val FirTypeRef.classLikeTypeOrNull: ConeClassLikeType?
get() = when (this) {
is FirImplicitBuiltinTypeRef -> type
is FirResolvedTypeRef -> type as? ConeClassLikeType ?: return false
else -> return false
is FirResolvedTypeRef -> type as? ConeClassLikeType
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
}
val FirTypeRef.isMarkedNullable: Boolean?
get() = classLikeTypeOrNull?.isMarkedNullable
val FirFunctionTypeRef.parametersCount: Int
get() = if (receiverTypeRef != null)
valueParameters.size + 1
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// WITH_RUNTIME
// WITH_COROUTINES
// COMMON_COROUTINES_TEST
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// WITH_RUNTIME
// WITH_COROUTINES
// COMMON_COROUTINES_TEST
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// WITH_RUNTIME
// WITH_COROUTINES
// COMMON_COROUTINES_TEST
@@ -1,4 +1,3 @@
// IGNORE_BACKEND_FIR: JVM_IR
// WITH_RUNTIME
// WITH_COROUTINES
// 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 })
// 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 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 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("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) {})<!>)
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) {})<!>)
@@ -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
fun use(fn: () -> Unit) {}