mirror of
https://github.com/roc-lang/roc.git
synced 2025-07-23 14:35:12 +00:00
Fixup transient closure captures during canonicalization
Closure captures can be transient, but previously, we did not handle that correctly. For example, in ``` x = "" inner = \{} -> x outer = \{} -> inner {} ``` `outer` captures `inner`, but `inner` captures `x`, and in the body of `outer`, we would not construct the closure data for `inner` correctly before calling it. There are a couple ways around this. 1. Update mono to do something when we are passed the captured environment of a closure, rather than attempting to construct a call-by-name's captured environment before callign it. 2. Fix-up closures during canonicalization to remove captured closures that themselves capture, and replace them with their captures. This patch does (2), since (1) is much more involved and is not likely to bring a lot of wins. In general I think it's reasonable to expect captured environments, even if transient, to be fairly shallow, so I don't think this will produce very large closure environments. Closes #2894
This commit is contained in:
parent
565ffacb9a
commit
e97ce32b88
2 changed files with 235 additions and 36 deletions
|
@ -7691,4 +7691,42 @@ mod solve_expr {
|
|||
"###
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn transient_captures() {
|
||||
infer_queries!(
|
||||
indoc!(
|
||||
r#"
|
||||
x = "abc"
|
||||
|
||||
getX = \{} -> x
|
||||
|
||||
h = \{} -> (getX {})
|
||||
#^{-1}
|
||||
|
||||
h {}
|
||||
"#
|
||||
),
|
||||
@"h : {}* -[[h(3) Str]]-> Str"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn transient_captures_after_def_ordering() {
|
||||
infer_queries!(
|
||||
indoc!(
|
||||
r#"
|
||||
h = \{} -> (getX {})
|
||||
#^{-1}
|
||||
|
||||
getX = \{} -> x
|
||||
|
||||
x = "abc"
|
||||
|
||||
h {}
|
||||
"#
|
||||
),
|
||||
@"h : {}* -[[h(1) Str]]-> Str"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue