mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-01 07:41:12 +00:00
clarify how we deal with a closure layout
This commit is contained in:
parent
b26f778ee0
commit
b0ef8b9b07
2 changed files with 60 additions and 31 deletions
|
@ -1025,7 +1025,6 @@ mod gen_primitives {
|
||||||
main : Float
|
main : Float
|
||||||
main =
|
main =
|
||||||
runEffect foo
|
runEffect foo
|
||||||
|
|
||||||
"#
|
"#
|
||||||
),
|
),
|
||||||
3.14,
|
3.14,
|
||||||
|
|
|
@ -1497,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_layout: Option<ClosureLayout<'a>>,
|
opt_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);
|
||||||
|
@ -1508,18 +1508,38 @@ fn build_specialized_proc<'a>(
|
||||||
proc_args.push((layout, *arg_name));
|
proc_args.push((layout, *arg_name));
|
||||||
}
|
}
|
||||||
|
|
||||||
// is the final argument symbol the closure symbol? then add the closure variable to the
|
// Given
|
||||||
// pattern variables
|
//
|
||||||
if pattern_symbols.last() == Some(&Symbol::ARG_CLOSURE) {
|
// foo =
|
||||||
let layout = closure_layout.unwrap().as_layout();
|
// x = 42
|
||||||
proc_args.push((layout, Symbol::ARG_CLOSURE));
|
//
|
||||||
|
// f = \{} -> x
|
||||||
|
//
|
||||||
|
// We desugar that into
|
||||||
|
//
|
||||||
|
// f = \{}, x -> x
|
||||||
|
//
|
||||||
|
// foo =
|
||||||
|
// x = 42
|
||||||
|
//
|
||||||
|
// f_closure = { ptr: f, closure: x }
|
||||||
|
//
|
||||||
|
// then
|
||||||
|
match opt_closure_layout {
|
||||||
|
Some(layout) if pattern_symbols.last() == Some(&Symbol::ARG_CLOSURE) => {
|
||||||
|
// here we define the lifted (now top-level) f function. Its final argument is `Symbol::ARG_CLOSURE`,
|
||||||
|
// it stores the closure structure (just an integer in this case)
|
||||||
|
proc_args.push((layout.as_layout(), Symbol::ARG_CLOSURE));
|
||||||
|
|
||||||
debug_assert_eq!(
|
debug_assert_eq!(
|
||||||
pattern_vars.len() + 1,
|
pattern_vars.len() + 1,
|
||||||
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 {
|
}
|
||||||
|
Some(layout) => {
|
||||||
|
// else if there is a closure layout, we're building the `f_closure` value
|
||||||
|
// that means we're really creating a ( function_ptr, closure_data ) pair
|
||||||
let ret_layout = layout_cache
|
let ret_layout = layout_cache
|
||||||
.from_var(&env.arena, ret_var, env.subs)
|
.from_var(&env.arena, ret_var, env.subs)
|
||||||
.unwrap_or_else(|err| panic!("TODO handle invalid function {:?}", err));
|
.unwrap_or_else(|err| panic!("TODO handle invalid function {:?}", err));
|
||||||
|
@ -1535,13 +1555,23 @@ fn build_specialized_proc<'a>(
|
||||||
Layout::Struct(env.arena.alloc([function_ptr_layout, closure_data_layout]));
|
Layout::Struct(env.arena.alloc([function_ptr_layout, closure_data_layout]));
|
||||||
|
|
||||||
return Ok((&[], closure_layout));
|
return Ok((&[], closure_layout));
|
||||||
} else {
|
}
|
||||||
|
None => {
|
||||||
|
// else we're making a normal function, no closure problems to worry about
|
||||||
|
// we'll just assert some things
|
||||||
|
|
||||||
|
// make sure there is not arg_closure argument without a closure layout
|
||||||
|
debug_assert!(pattern_symbols.last() != Some(&Symbol::ARG_CLOSURE));
|
||||||
|
|
||||||
|
// since this is not a closure, the number of arguments should match between symbols
|
||||||
|
// and layout
|
||||||
debug_assert_eq!(
|
debug_assert_eq!(
|
||||||
pattern_vars.len(),
|
pattern_vars.len(),
|
||||||
pattern_symbols.len(),
|
pattern_symbols.len(),
|
||||||
"Tried to zip two vecs with different lengths!"
|
"Tried to zip two vecs with different lengths!"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let proc_args = proc_args.into_bump_slice();
|
let proc_args = proc_args.into_bump_slice();
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue