Skip to content

Commit 26487d2

Browse files
anton-bannykhSpace
authored andcommitted
JS IR: materialize Unit in lambdas
^KT-52010 fixed (cherry picked from commit 281e381)
1 parent 4cbf375 commit 26487d2

File tree

5 files changed

+87
-0
lines changed

5 files changed

+87
-0
lines changed

compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/InteropCallableReferenceLowering.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import org.jetbrains.kotlin.ir.expressions.impl.*
2424
import org.jetbrains.kotlin.ir.symbols.*
2525
import org.jetbrains.kotlin.ir.types.IrType
2626
import org.jetbrains.kotlin.ir.types.classifierOrNull
27+
import org.jetbrains.kotlin.ir.types.isUnit
2728
import org.jetbrains.kotlin.ir.util.*
2829
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
2930
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
@@ -147,6 +148,11 @@ class InteropCallableReferenceLowering(val context: JsIrBackendContext) : BodyLo
147148
// Fix parents of declarations inside body
148149
body.patchDeclarationParents(lambdaDeclaration)
149150

151+
if (invokeFun.returnType.isUnit()) {
152+
val unitValue = JsIrBuilder.buildGetObjectValue(context.irBuiltIns.unitType, context.irBuiltIns.unitClass)
153+
(body as IrBlockBody).statements.add(IrReturnImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, context.irBuiltIns.nothingType, lambdaDeclaration.symbol, unitValue))
154+
}
155+
150156
return body as IrBlockBody
151157
}
152158

js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/BoxJsTestGenerated.java

Lines changed: 12 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/ir/IrBoxJsTestGenerated.java

Lines changed: 12 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// EXPECTED_REACHABLE_NODES: 1285
2+
3+
fun <T> rawReturnValue(fn: () -> T): Any {
4+
return fn() as Any
5+
}
6+
7+
fun unitFun() {}
8+
9+
fun charFun(): Char = 'a'
10+
11+
value class VC(val v: Int)
12+
13+
fun vcFun(): VC = VC(1)
14+
15+
16+
17+
fun box(): String {
18+
if (rawReturnValue { unitFun() } != Unit) return "fail1.1"
19+
if (rawReturnValue<Unit> { unitFun() } != Unit) return "fail1.2"
20+
if (rawReturnValue<Any> { unitFun() } != Unit) return "fail1.3"
21+
22+
val boxedA: Any = 'a'
23+
24+
if (rawReturnValue { charFun() } != boxedA) return "fail2.1"
25+
if (rawReturnValue<Char> { charFun() } != boxedA) return "fail2.2"
26+
if (rawReturnValue<Any> { charFun() } != boxedA) return "fail2.3"
27+
28+
val boxed1: Any = VC(1)
29+
30+
if (rawReturnValue { vcFun() } != boxed1) return "fail3.1"
31+
if (rawReturnValue<VC> { vcFun() } != boxed1) return "fail3.2"
32+
if (rawReturnValue<Any> { vcFun() } != boxed1) return "fail3.3"
33+
34+
return "OK"
35+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// EXPECTED_REACHABLE_NODES: 1274
2+
3+
fun box(): String {
4+
instance = Holder()
5+
instance?.applyAndRet<Unit> { sideEffect("left") } ?: sideEffect("right")
6+
7+
if (log == "left") return "OK" else return "fail: $log"
8+
}
9+
10+
var log = ""
11+
12+
fun sideEffect(msg: String) {
13+
log += msg
14+
}
15+
16+
var instance: Holder? = null
17+
18+
class Holder() {
19+
fun <T> applyAndRet(block: () -> T): T {
20+
return block()
21+
}
22+
}

0 commit comments

Comments
 (0)