File tree 3 files changed +29
-1
lines changed
testsuite/tests/letrec-compilation
3 files changed +29
-1
lines changed Original file line number Diff line number Diff line change @@ -662,6 +662,15 @@ let rec split_static_function lfun block_var local_idents lam :
662
662
| Levent (lam , lev ) ->
663
663
let + lam = split_static_function lfun block_var local_idents lam in
664
664
Levent (lam, lev)
665
+ | Lregion (lam , layout_fun ) ->
666
+ (* The type-checker forbids recursive values from being allocated on the
667
+ stack, so this region is only here to collect temporary allocations.
668
+ In particular the function itself does not capture any stack-allocated
669
+ variables, so we can lift it out of the region. *)
670
+ let + lam = split_static_function lfun block_var local_idents lam in
671
+ (* The new expression returns the closure block instead of the function *)
672
+ ignore layout_fun;
673
+ Lregion (lam, layout_block)
665
674
| Lmutvar _
666
675
| Lconst _
667
676
| Lapply _
@@ -671,7 +680,6 @@ let rec split_static_function lfun block_var local_idents lam :
671
680
| Lassign _
672
681
| Lsend _
673
682
| Lifused _
674
- | Lregion _
675
683
| Lexclave _ ->
676
684
Misc. fatal_errorf
677
685
" letrec binding is not a static function:@ lfun=%a@ lam=%a"
Original file line number Diff line number Diff line change
1
+ (* TEST *)
2
+
3
+ (* Recursive values are not allowed to be stack-allocated, but their
4
+ defining expressions are allowed to make allocations on the stack.
5
+ This can introduce a region around the whole definition. *)
6
+
7
+ let rec f =
8
+ let p = local_ (fun msg -> print_string msg) in
9
+ p " hello, " ;
10
+ p " world!" ;
11
+ print_newline () ;
12
+ fun x -> f x
13
+
14
+ (* Original bug report: unused function *)
15
+ let rec foo =
16
+ let _f x = x, foo in
17
+ function
18
+ | None -> foo None
19
+ | Some x -> x
Original file line number Diff line number Diff line change
1
+ hello, world!
You can’t perform that action at this time.
0 commit comments