diff --git a/ocaml/lambda/value_rec_compiler.ml b/ocaml/lambda/value_rec_compiler.ml index a010fb65029..721a568f97b 100644 --- a/ocaml/lambda/value_rec_compiler.ml +++ b/ocaml/lambda/value_rec_compiler.ml @@ -662,6 +662,15 @@ let rec split_static_function lfun block_var local_idents lam : | Levent (lam, lev) -> let+ lam = split_static_function lfun block_var local_idents lam in Levent (lam, lev) + | Lregion (lam, layout_fun) -> + (* The type-checker forbids recursive values from being allocated on the + stack, so this region is only here to collect temporary allocations. + In particular the function itself does not capture any stack-allocated + variables, so we can lift it out of the region. *) + let+ lam = split_static_function lfun block_var local_idents lam in + (* The new expression returns the closure block instead of the function *) + ignore layout_fun; + Lregion (lam, layout_block) | Lmutvar _ | Lconst _ | Lapply _ @@ -671,7 +680,6 @@ let rec split_static_function lfun block_var local_idents lam : | Lassign _ | Lsend _ | Lifused _ - | Lregion _ | Lexclave _ -> Misc.fatal_errorf "letrec binding is not a static function:@ lfun=%a@ lam=%a" diff --git a/ocaml/testsuite/tests/letrec-compilation/region.ml b/ocaml/testsuite/tests/letrec-compilation/region.ml new file mode 100644 index 00000000000..84104036d69 --- /dev/null +++ b/ocaml/testsuite/tests/letrec-compilation/region.ml @@ -0,0 +1,19 @@ +(* TEST *) + +(* Recursive values are not allowed to be stack-allocated, but their + defining expressions are allowed to make allocations on the stack. + This can introduce a region around the whole definition. *) + +let rec f = + let p = local_ (fun msg -> print_string msg) in + p "hello, "; + p "world!"; + print_newline (); + fun x -> f x + +(* Original bug report: unused function *) +let rec foo = + let _f x = x, foo in + function + | None -> foo None + | Some x -> x diff --git a/ocaml/testsuite/tests/letrec-compilation/region.reference b/ocaml/testsuite/tests/letrec-compilation/region.reference new file mode 100644 index 00000000000..270c611ee72 --- /dev/null +++ b/ocaml/testsuite/tests/letrec-compilation/region.reference @@ -0,0 +1 @@ +hello, world!