[Wasm] traverse lambdas (lowered to IrRichFunctionReference) during TailrecLowering to rename captured variables (^KT-83995)
diff --git a/analysis/low-level-api-fir/tests-gen/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLBlackBoxTestGenerated.java b/analysis/low-level-api-fir/tests-gen/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLBlackBoxTestGenerated.java index c4df2ce..d81913e 100644 --- a/analysis/low-level-api-fir/tests-gen/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLBlackBoxTestGenerated.java +++ b/analysis/low-level-api-fir/tests-gen/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLBlackBoxTestGenerated.java
@@ -41502,6 +41502,12 @@ public void testLambda_kt80285() { runTest("compiler/testData/codegen/box/lambda/lambda_kt80285.kt"); } + + @Test + @TestMetadata("lambda_kt83995.kt") + public void testLambda_kt83995() { + runTest("compiler/testData/codegen/box/lambda/lambda_kt83995.kt"); + } } @Nested
diff --git a/analysis/low-level-api-fir/tests-gen/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLReversedBlackBoxTestGenerated.java b/analysis/low-level-api-fir/tests-gen/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLReversedBlackBoxTestGenerated.java index 15b7302..8a83848 100644 --- a/analysis/low-level-api-fir/tests-gen/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLReversedBlackBoxTestGenerated.java +++ b/analysis/low-level-api-fir/tests-gen/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLReversedBlackBoxTestGenerated.java
@@ -41502,6 +41502,12 @@ public void testLambda_kt80285() { runTest("compiler/testData/codegen/box/lambda/lambda_kt80285.kt"); } + + @Test + @TestMetadata("lambda_kt83995.kt") + public void testLambda_kt83995() { + runTest("compiler/testData/codegen/box/lambda/lambda_kt83995.kt"); + } } @Nested
diff --git a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/WasmLoweringPhases.kt b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/WasmLoweringPhases.kt index c662759..95509e2 100644 --- a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/WasmLoweringPhases.kt +++ b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/WasmLoweringPhases.kt
@@ -150,7 +150,7 @@ ::ExpectDeclarationsRemoveLowering, ::RangeContainsLowering, - ::TailrecLowering, + ::WasmTailrecLowering, ::EnumWhenLowering, ::EnumClassConstructorLowering,
diff --git a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/lower/WasmTailrecLowering.kt b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/lower/WasmTailrecLowering.kt new file mode 100644 index 0000000..d6f6419 --- /dev/null +++ b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/lower/WasmTailrecLowering.kt
@@ -0,0 +1,16 @@ +/* + * Copyright 2010-2026 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.backend.wasm.lower + +import org.jetbrains.kotlin.backend.common.lower.TailrecLowering +import org.jetbrains.kotlin.backend.wasm.WasmBackendContext +import org.jetbrains.kotlin.ir.expressions.IrRichFunctionReference +import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin + +internal class WasmTailrecLowering(context: WasmBackendContext) : TailrecLowering(context) { + override fun followRichFunctionReference(reference: IrRichFunctionReference): Boolean = + reference.origin == IrStatementOrigin.LAMBDA +} \ No newline at end of file
diff --git a/compiler/testData/codegen/box/lambda/lambda_kt83995.kt b/compiler/testData/codegen/box/lambda/lambda_kt83995.kt new file mode 100644 index 0000000..b240bb8 --- /dev/null +++ b/compiler/testData/codegen/box/lambda/lambda_kt83995.kt
@@ -0,0 +1,18 @@ +// WITH_STDLIB + +fun blockCall(block: () -> Int): Int = block() + +tailrec fun test(n: Int, acc: Int): Int = + if (n > 0) { + val s = blockCall { acc + 1 } + test(n - 1, s) + } else { + acc + } + + +fun box(): String { + val result = test(2, 0) + if (result != 2) return "Fail: result = $result" + return "OK" +} \ No newline at end of file