mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-03 00:24:34 +00:00
code gen for closures that are by-unification, not because they capture anything
This commit is contained in:
parent
9cecfe3558
commit
b26f778ee0
2 changed files with 20 additions and 4 deletions
|
@ -1005,7 +1005,6 @@ mod gen_primitives {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[ignore]
|
|
||||||
fn io_poc_desugared() {
|
fn io_poc_desugared() {
|
||||||
assert_evals_to!(
|
assert_evals_to!(
|
||||||
indoc!(
|
indoc!(
|
||||||
|
|
|
@ -1466,12 +1466,13 @@ fn build_specialized_proc_from_var<'a>(
|
||||||
) -> Result<(&'a [(Layout<'a>, Symbol)], Layout<'a>), LayoutProblem> {
|
) -> Result<(&'a [(Layout<'a>, Symbol)], Layout<'a>), LayoutProblem> {
|
||||||
match env.subs.get_without_compacting(fn_var).content {
|
match env.subs.get_without_compacting(fn_var).content {
|
||||||
Content::Structure(FlatType::Func(pattern_vars, closure_var, ret_var)) => {
|
Content::Structure(FlatType::Func(pattern_vars, closure_var, ret_var)) => {
|
||||||
|
let closure_layout = ClosureLayout::from_var(env.arena, env.subs, closure_var)?;
|
||||||
build_specialized_proc(
|
build_specialized_proc(
|
||||||
env,
|
env,
|
||||||
layout_cache,
|
layout_cache,
|
||||||
pattern_symbols,
|
pattern_symbols,
|
||||||
&pattern_vars,
|
&pattern_vars,
|
||||||
Some(closure_var),
|
closure_layout,
|
||||||
ret_var,
|
ret_var,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -1496,7 +1497,7 @@ fn build_specialized_proc<'a>(
|
||||||
layout_cache: &mut LayoutCache<'a>,
|
layout_cache: &mut LayoutCache<'a>,
|
||||||
pattern_symbols: &[Symbol],
|
pattern_symbols: &[Symbol],
|
||||||
pattern_vars: &[Variable],
|
pattern_vars: &[Variable],
|
||||||
closure_var: Option<Variable>,
|
closure_layout: Option<ClosureLayout<'a>>,
|
||||||
ret_var: Variable,
|
ret_var: Variable,
|
||||||
) -> Result<(&'a [(Layout<'a>, Symbol)], Layout<'a>), LayoutProblem> {
|
) -> Result<(&'a [(Layout<'a>, Symbol)], Layout<'a>), LayoutProblem> {
|
||||||
let mut proc_args = Vec::with_capacity_in(pattern_vars.len(), &env.arena);
|
let mut proc_args = Vec::with_capacity_in(pattern_vars.len(), &env.arena);
|
||||||
|
@ -1510,7 +1511,7 @@ fn build_specialized_proc<'a>(
|
||||||
// is the final argument symbol the closure symbol? then add the closure variable to the
|
// is the final argument symbol the closure symbol? then add the closure variable to the
|
||||||
// pattern variables
|
// pattern variables
|
||||||
if pattern_symbols.last() == Some(&Symbol::ARG_CLOSURE) {
|
if pattern_symbols.last() == Some(&Symbol::ARG_CLOSURE) {
|
||||||
let layout = layout_cache.from_var(&env.arena, closure_var.unwrap(), env.subs)?;
|
let layout = closure_layout.unwrap().as_layout();
|
||||||
proc_args.push((layout, Symbol::ARG_CLOSURE));
|
proc_args.push((layout, Symbol::ARG_CLOSURE));
|
||||||
|
|
||||||
debug_assert_eq!(
|
debug_assert_eq!(
|
||||||
|
@ -1518,6 +1519,22 @@ fn build_specialized_proc<'a>(
|
||||||
pattern_symbols.len(),
|
pattern_symbols.len(),
|
||||||
"Tried to zip two vecs with different lengths!"
|
"Tried to zip two vecs with different lengths!"
|
||||||
);
|
);
|
||||||
|
} else if let Some(layout) = closure_layout {
|
||||||
|
let ret_layout = layout_cache
|
||||||
|
.from_var(&env.arena, ret_var, env.subs)
|
||||||
|
.unwrap_or_else(|err| panic!("TODO handle invalid function {:?}", err));
|
||||||
|
|
||||||
|
let closure_data_layout = layout.as_layout();
|
||||||
|
let function_ptr_layout = Layout::FunctionPointer(
|
||||||
|
env.arena
|
||||||
|
.alloc([Layout::Struct(&[]), closure_data_layout.clone()]),
|
||||||
|
env.arena.alloc(ret_layout),
|
||||||
|
);
|
||||||
|
|
||||||
|
let closure_layout =
|
||||||
|
Layout::Struct(env.arena.alloc([function_ptr_layout, closure_data_layout]));
|
||||||
|
|
||||||
|
return Ok((&[], closure_layout));
|
||||||
} else {
|
} else {
|
||||||
debug_assert_eq!(
|
debug_assert_eq!(
|
||||||
pattern_vars.len(),
|
pattern_vars.len(),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue