diff --git a/src/Fable.Cli/CHANGELOG.md b/src/Fable.Cli/CHANGELOG.md index 2019c5e103..8cc96356d9 100644 --- a/src/Fable.Cli/CHANGELOG.md +++ b/src/Fable.Cli/CHANGELOG.md @@ -6,6 +6,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +#### Rust + +* Fixed recursive lambda captured idents cloning (by @ncave) + ## 4.4.0 - 2023-10-24 ### Changed diff --git a/src/Fable.Transforms/Rust/Fable2Rust.fs b/src/Fable.Transforms/Rust/Fable2Rust.fs index 5f8a6ca597..acf32ed08a 100644 --- a/src/Fable.Transforms/Rust/Fable2Rust.fs +++ b/src/Fable.Transforms/Rust/Fable2Rust.fs @@ -3269,7 +3269,6 @@ module Util = makeLibCall com ctx None "Native" ("fix" + argCount) fixCallArgs else fnBody - let closureExpr = mkClosureExpr true fnDecl fnBody let cloneStmts = // clone captured idents (in move closures) // skip non-local idents (e.g. module let bindings) @@ -3283,8 +3282,16 @@ module Util = letExpr |> mkSemiStmt) |> Seq.toList let closureExpr = - if List.isEmpty cloneStmts then closureExpr - else mkStmtBlockExpr (cloneStmts @ [closureExpr |> mkExprStmt]) + if List.isEmpty cloneStmts then + mkClosureExpr true fnDecl fnBody + else + let fnBody = + // additional captured idents cloning for recursive lambdas + if isRecursive && not isTailRec then + mkStmtBlockExpr (cloneStmts @ [fnBody |> mkExprStmt]) + else fnBody + let closureExpr = mkClosureExpr true fnDecl fnBody + mkStmtBlockExpr (cloneStmts @ [closureExpr |> mkExprStmt]) let funcWrap = getLibraryImportName com ctx "Native" ("Func" + argCount) makeCall [funcWrap; "new"] None [closureExpr]