module thunk is function

This commit is contained in:
Folkert 2021-05-22 14:57:25 +02:00
parent 43c4f24515
commit 3b47fbc89a
3 changed files with 76 additions and 13 deletions

View file

@ -2048,8 +2048,6 @@ fn update<'a>(
&& state.dependencies.solved_all()
&& state.goal_phase == Phase::MakeSpecializations
{
Proc::insert_refcount_operations(arena, &mut state.procedures);
// display the mono IR of the module, for debug purposes
if roc_mono::ir::PRETTY_PRINT_IR_SYMBOLS {
let procs_string = state
@ -2062,6 +2060,7 @@ fn update<'a>(
println!("{}", result);
}
Proc::insert_refcount_operations(arena, &mut state.procedures);
Proc::optimize_refcount_operations(
arena,

View file

@ -6079,7 +6079,7 @@ fn call_by_name<'a>(
}
Ok(layout) if procs.module_thunks.contains(&proc_name) => {
// here we turn a call to a module thunk into forcing of that thunk
debug_assert!(loc_args.is_empty());
if loc_args.is_empty() {
call_by_name_module_thunk(
env,
procs,
@ -6090,6 +6090,54 @@ fn call_by_name<'a>(
assigned,
hole,
)
} else if let Layout::Closure(arg_layouts, lambda_set, ret_layout) = layout {
// here we turn a call to a module thunk into forcing of that thunk
// the thunk represents the closure environment for the body, so we then match
// on the closure environment to perform the call that the body represents.
//
// Example:
//
// > main = parseA "foo" "bar"
// > parseA = Str.concat
let closure_data_symbol = env.unique_symbol();
let arena = env.arena;
let arg_symbols = Vec::from_iter_in(
loc_args
.iter()
.map(|(_, arg_expr)| possible_reuse_symbol(env, procs, &arg_expr.value)),
arena,
)
.into_bump_slice();
let result = match_on_lambda_set(
env,
lambda_set,
closure_data_symbol,
arg_symbols,
arg_layouts,
*ret_layout,
assigned,
hole,
);
let result = call_by_name_module_thunk(
env,
procs,
fn_var,
proc_name,
env.arena.alloc(layout),
layout_cache,
closure_data_symbol,
env.arena.alloc(result),
);
let iter = loc_args.into_iter().rev().zip(arg_symbols.iter().rev());
assign_to_symbols(env, procs, layout_cache, iter, result)
} else {
unreachable!("calling a non-closure layout")
}
}
Ok(Layout::FunctionPointer(argument_layouts, ret_layout)) => call_by_name_help(
env,

View file

@ -2426,3 +2426,19 @@ fn increment_or_double_closure() {
i64
);
}
#[test]
fn module_thunk_is_function() {
assert_evals_to!(
indoc!(
r#"
app "test" provides [ main ] to "./platform"
main = helper "foo" "bar"
helper = Str.concat
"#
),
RocStr::from_slice(b"foobar"),
RocStr
);
}