mirror of
https://github.com/roc-lang/roc.git
synced 2025-08-03 19:58:18 +00:00
Ensure that closures inside recursive closures capture correctly
With a code like ``` thenDo = \x, callback -> callback x f = \{} -> code = 10u16 bf = \{} -> thenDo code \_ -> bf {} bf {} ``` The lambda `\_ -> bf {}` must capture `bf`. Previously, this would not happen correctly, because we assumed that mutually recursive functions (including singleton recursive functions, like `bf` here) cannot capture themselves. Of course, that premise does not hold in general. Instead, we should have mutually recursive functions capture the closure (haha, get it) of values captured by all functions constituting the mutual recursion. Then, any nested closures can capture outer recursive closures' values appropriately.
This commit is contained in:
parent
ceacc1792d
commit
e8a29d2df4
3 changed files with 69 additions and 18 deletions
|
@ -8778,4 +8778,32 @@ mod solve_expr {
|
|||
@"main : List w_a"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn recursive_closure_with_transiently_used_capture() {
|
||||
infer_queries!(
|
||||
indoc!(
|
||||
r#"
|
||||
app "test" provides [f] to "./platform"
|
||||
|
||||
thenDo = \x, callback ->
|
||||
callback x
|
||||
|
||||
f = \{} ->
|
||||
code = 10u16
|
||||
|
||||
bf = \{} ->
|
||||
#^^{-1}
|
||||
thenDo code \_ -> bf {}
|
||||
# ^^^^^^^^^^^
|
||||
|
||||
bf {}
|
||||
"#
|
||||
),
|
||||
@r###"
|
||||
bf : {} -[[bf(5) U16]]-> *
|
||||
\_ -> bf {} : U16 -[[6 U16]]-> *
|
||||
"###
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue