Correctly compile rvalue closures defined in nested defines to lvalues

Previously, a program like

```
main =
  f =
    n = 1
    \{} -[#lam]-> n  # suppose lambda set = #lam
  f {}
```

would be transformed to

```
main =
  n = 1
  f = \{} -[#lam]-> n
  f {}
```

However, the IR lowering procedure is such that we would then associate
`f` as definining the procedure given the lambda set `#lam`. This is not
correct, as `f` is really a function pointer in this circumstance,
rather than the definer of `#lam`.

Instead, the transformation we want to perform is

```
main =
  n = 1
  #lam = \{} -[#lam]-> n
  f = #lam
  f {}
```

Which is what this patch does

Closes #2403
This commit is contained in:
Ayaz Hafiz 2022-12-01 15:47:18 -06:00
parent 68e364d897
commit 9181ed8092
No known key found for this signature in database
GPG key ID: 0E2A37416A25EF58
3 changed files with 85 additions and 10 deletions

View file

@ -0,0 +1,8 @@
procedure Test.4 (Test.5, Test.3):
ret Test.3;
procedure Test.0 ():
let Test.3 : I64 = 1i64;
let Test.7 : {} = Struct {};
let Test.2 : I64 = CallByName Test.4 Test.7 Test.3;
ret Test.2;

View file

@ -2066,3 +2066,19 @@ fn function_pointer_lambda_set() {
"#
)
}
#[mono_test]
fn anonymous_closure_lifted_to_named_issue_2403() {
indoc!(
r#"
app "test" provides [main] to "./platform"
main =
f =
n = 1
\{} -> n
g = f {}
g
"#
)
}