mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-01 15:51:12 +00:00
Merge remote-tracking branch 'origin/can-builtins-simplify' into list-range
This commit is contained in:
commit
f2c144f58c
55 changed files with 2303 additions and 1059 deletions
|
@ -655,10 +655,10 @@ pub fn lowlevel_borrow_signature(arena: &Bump, op: LowLevel) -> &[bool] {
|
|||
ListMap3 => arena.alloc_slice_copy(&[owned, owned, owned, irrelevant]),
|
||||
ListKeepIf | ListKeepOks | ListKeepErrs => arena.alloc_slice_copy(&[owned, borrowed]),
|
||||
ListContains => arena.alloc_slice_copy(&[borrowed, irrelevant]),
|
||||
ListWalk => arena.alloc_slice_copy(&[owned, irrelevant, owned]),
|
||||
ListWalkBackwards => arena.alloc_slice_copy(&[owned, irrelevant, owned]),
|
||||
ListRange => arena.alloc_slice_copy(&[irrelevant, irrelevant]),
|
||||
ListSum | ListProduct => arena.alloc_slice_copy(&[borrowed]),
|
||||
ListWalk | ListWalkUntil | ListWalkBackwards => {
|
||||
arena.alloc_slice_copy(&[owned, irrelevant, owned])
|
||||
}
|
||||
|
||||
// TODO when we have lists with capacity (if ever)
|
||||
// List.append should own its first argument
|
||||
|
|
|
@ -441,7 +441,7 @@ fn expand_and_cancel<'a>(env: &mut Env<'a, '_>, stmt: &'a Stmt<'a>) -> &'a Stmt<
|
|||
structure,
|
||||
index,
|
||||
field_layouts,
|
||||
..
|
||||
wrapped,
|
||||
} => {
|
||||
let entry = env
|
||||
.alias_map
|
||||
|
@ -450,6 +450,15 @@ fn expand_and_cancel<'a>(env: &mut Env<'a, '_>, stmt: &'a Stmt<'a>) -> &'a Stmt<
|
|||
|
||||
entry.insert(*index, symbol);
|
||||
|
||||
// fixes https://github.com/rtfeldman/roc/issues/1099
|
||||
if matches!(
|
||||
wrapped,
|
||||
Wrapped::SingleElementRecord | Wrapped::RecordOrSingleTagUnion
|
||||
) {
|
||||
env.layout_map
|
||||
.insert(*structure, Layout::Struct(field_layouts));
|
||||
}
|
||||
|
||||
// if the field is a struct, we know its constructor too!
|
||||
let field_layout = &field_layouts[*index as usize];
|
||||
env.try_insert_struct_info(symbol, field_layout);
|
||||
|
|
|
@ -558,13 +558,7 @@ impl<'a> Procs<'a> {
|
|||
}
|
||||
}
|
||||
Err(error) => {
|
||||
let error_msg = format!(
|
||||
"TODO generate a RuntimeError message for {:?}",
|
||||
error
|
||||
);
|
||||
self.runtime_errors
|
||||
.insert(symbol, env.arena.alloc(error_msg));
|
||||
panic!();
|
||||
panic!("TODO generate a RuntimeError message for {:?}", error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -671,11 +665,7 @@ impl<'a> Procs<'a> {
|
|||
self.specialized.insert((symbol, layout), Done(proc));
|
||||
}
|
||||
Err(error) => {
|
||||
let error_msg =
|
||||
format!("TODO generate a RuntimeError message for {:?}", error);
|
||||
self.runtime_errors
|
||||
.insert(symbol, env.arena.alloc(error_msg));
|
||||
panic!();
|
||||
panic!("TODO generate a RuntimeError message for {:?}", error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -699,7 +689,6 @@ fn add_pending<'a>(
|
|||
#[derive(Default)]
|
||||
pub struct Specializations<'a> {
|
||||
by_symbol: MutMap<Symbol, MutMap<Layout<'a>, Proc<'a>>>,
|
||||
runtime_errors: MutSet<Symbol>,
|
||||
}
|
||||
|
||||
impl<'a> Specializations<'a> {
|
||||
|
@ -715,32 +704,15 @@ impl<'a> Specializations<'a> {
|
|||
!procs_by_layout.contains_key(&layout) || procs_by_layout.get(&layout) == Some(&proc)
|
||||
);
|
||||
|
||||
// We shouldn't already have a runtime error recorded for this symbol
|
||||
debug_assert!(!self.runtime_errors.contains(&symbol));
|
||||
|
||||
procs_by_layout.insert(layout, proc);
|
||||
}
|
||||
|
||||
pub fn runtime_error(&mut self, symbol: Symbol) {
|
||||
// We shouldn't already have a normal proc recorded for this symbol
|
||||
debug_assert!(!self.by_symbol.contains_key(&symbol));
|
||||
|
||||
self.runtime_errors.insert(symbol);
|
||||
}
|
||||
|
||||
pub fn into_owned(self) -> (MutMap<Symbol, MutMap<Layout<'a>, Proc<'a>>>, MutSet<Symbol>) {
|
||||
(self.by_symbol, self.runtime_errors)
|
||||
}
|
||||
|
||||
pub fn len(&self) -> usize {
|
||||
let runtime_errors: usize = self.runtime_errors.len();
|
||||
let specializations: usize = self.by_symbol.len();
|
||||
|
||||
runtime_errors + specializations
|
||||
self.by_symbol.len()
|
||||
}
|
||||
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.len() == 0
|
||||
self.by_symbol.is_empty()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1696,13 +1668,15 @@ pub fn specialize_all<'a>(
|
|||
Ok((proc, layout)) => {
|
||||
procs.specialized.insert((name, layout), Done(proc));
|
||||
}
|
||||
Err(error) => {
|
||||
let error_msg = env.arena.alloc(format!(
|
||||
"TODO generate a RuntimeError message for {:?}",
|
||||
error
|
||||
));
|
||||
Err(SpecializeFailure {
|
||||
problem: _,
|
||||
attempted_layout,
|
||||
}) => {
|
||||
let proc = generate_runtime_error_function(env, name, attempted_layout);
|
||||
|
||||
procs.runtime_errors.insert(name, error_msg);
|
||||
procs
|
||||
.specialized
|
||||
.insert((name, attempted_layout), Done(proc));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1758,13 +1732,14 @@ pub fn specialize_all<'a>(
|
|||
procs.specialized.insert((name, layout), Done(proc));
|
||||
}
|
||||
}
|
||||
Err(error) => {
|
||||
let error_msg = env.arena.alloc(format!(
|
||||
"TODO generate a RuntimeError message for {:?}",
|
||||
error
|
||||
));
|
||||
Err(SpecializeFailure {
|
||||
attempted_layout, ..
|
||||
}) => {
|
||||
let proc = generate_runtime_error_function(env, name, attempted_layout);
|
||||
|
||||
procs.runtime_errors.insert(name, error_msg);
|
||||
procs
|
||||
.specialized
|
||||
.insert((name, attempted_layout), Done(proc));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1774,6 +1749,47 @@ pub fn specialize_all<'a>(
|
|||
procs
|
||||
}
|
||||
|
||||
fn generate_runtime_error_function<'a>(
|
||||
env: &mut Env<'a, '_>,
|
||||
name: Symbol,
|
||||
layout: Layout<'a>,
|
||||
) -> Proc<'a> {
|
||||
let (arg_layouts, ret_layout) = match layout {
|
||||
Layout::FunctionPointer(a, r) => (a, *r),
|
||||
_ => (&[] as &[_], layout),
|
||||
};
|
||||
|
||||
let mut args = Vec::with_capacity_in(arg_layouts.len(), env.arena);
|
||||
|
||||
for arg in arg_layouts {
|
||||
args.push((*arg, env.unique_symbol()));
|
||||
}
|
||||
|
||||
let mut msg = bumpalo::collections::string::String::with_capacity_in(80, env.arena);
|
||||
use std::fmt::Write;
|
||||
write!(
|
||||
&mut msg,
|
||||
"The {:?} function could not be generated, likely due to a type error.",
|
||||
name
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
eprintln!("emitted runtime error function {:?}", &msg);
|
||||
|
||||
let runtime_error = Stmt::RuntimeError(msg.into_bump_str());
|
||||
|
||||
Proc {
|
||||
name,
|
||||
args: args.into_bump_slice(),
|
||||
body: runtime_error,
|
||||
closure_data_layout: None,
|
||||
ret_layout,
|
||||
is_self_recursive: SelfRecursive::NotSelfRecursive,
|
||||
must_own_arguments: false,
|
||||
host_exposed_layouts: HostExposedLayouts::NotHostExposed,
|
||||
}
|
||||
}
|
||||
|
||||
fn specialize_external<'a>(
|
||||
env: &mut Env<'a, '_>,
|
||||
procs: &mut Procs<'a>,
|
||||
|
@ -2270,6 +2286,14 @@ fn build_specialized_proc<'a>(
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct SpecializeFailure<'a> {
|
||||
/// The layout we attempted to create
|
||||
attempted_layout: Layout<'a>,
|
||||
/// The problem we ran into while creating it
|
||||
problem: LayoutProblem,
|
||||
}
|
||||
|
||||
fn specialize<'a>(
|
||||
env: &mut Env<'a, '_>,
|
||||
procs: &mut Procs<'a>,
|
||||
|
@ -2277,7 +2301,7 @@ fn specialize<'a>(
|
|||
layout_cache: &mut LayoutCache<'a>,
|
||||
pending: PendingSpecialization,
|
||||
partial_proc: PartialProc<'a>,
|
||||
) -> Result<(Proc<'a>, Layout<'a>), LayoutProblem> {
|
||||
) -> Result<(Proc<'a>, Layout<'a>), SpecializeFailure<'a>> {
|
||||
let PendingSpecialization {
|
||||
solved_type,
|
||||
host_exposed_aliases,
|
||||
|
@ -2321,7 +2345,7 @@ fn specialize_solved_type<'a>(
|
|||
solved_type: SolvedType,
|
||||
host_exposed_aliases: MutMap<Symbol, SolvedType>,
|
||||
partial_proc: PartialProc<'a>,
|
||||
) -> Result<(Proc<'a>, Layout<'a>), LayoutProblem> {
|
||||
) -> Result<(Proc<'a>, Layout<'a>), SpecializeFailure<'a>> {
|
||||
// add the specializations that other modules require of us
|
||||
use roc_solve::solve::instantiate_rigids;
|
||||
|
||||
|
@ -2330,6 +2354,10 @@ fn specialize_solved_type<'a>(
|
|||
|
||||
let fn_var = introduce_solved_type_to_subs(env, &solved_type);
|
||||
|
||||
let attempted_layout = layout_cache
|
||||
.from_var(&env.arena, fn_var, env.subs)
|
||||
.unwrap_or_else(|err| panic!("TODO handle invalid function {:?}", err));
|
||||
|
||||
// make sure rigid variables in the annotation are converted to flex variables
|
||||
instantiate_rigids(env.subs, partial_proc.annotation);
|
||||
|
||||
|
@ -2353,17 +2381,25 @@ fn specialize_solved_type<'a>(
|
|||
|
||||
match specialized {
|
||||
Ok(proc) => {
|
||||
let layout = layout_cache
|
||||
.from_var(&env.arena, fn_var, env.subs)
|
||||
.unwrap_or_else(|err| panic!("TODO handle invalid function {:?}", err));
|
||||
// when successful, the layout after unification should be the layout before unification
|
||||
debug_assert_eq!(
|
||||
attempted_layout,
|
||||
layout_cache
|
||||
.from_var(&env.arena, fn_var, env.subs)
|
||||
.unwrap_or_else(|err| panic!("TODO handle invalid function {:?}", err))
|
||||
);
|
||||
|
||||
env.subs.rollback_to(snapshot);
|
||||
layout_cache.rollback_to(cache_snapshot);
|
||||
Ok((proc, layout))
|
||||
Ok((proc, attempted_layout))
|
||||
}
|
||||
Err(error) => {
|
||||
env.subs.rollback_to(snapshot);
|
||||
layout_cache.rollback_to(cache_snapshot);
|
||||
Err(error)
|
||||
Err(SpecializeFailure {
|
||||
problem: error,
|
||||
attempted_layout,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2803,11 +2839,69 @@ pub fn with_hole<'a>(
|
|||
variant_var,
|
||||
name: tag_name,
|
||||
arguments: args,
|
||||
..
|
||||
ext_var,
|
||||
} => {
|
||||
use crate::layout::UnionVariant::*;
|
||||
let arena = env.arena;
|
||||
|
||||
let desc = env.subs.get_without_compacting(variant_var);
|
||||
|
||||
if let Content::Structure(FlatType::Func(arg_vars, _, ret_var)) = desc.content {
|
||||
let mut loc_pattern_args = vec![];
|
||||
let mut loc_expr_args = vec![];
|
||||
|
||||
let proc_symbol = env.unique_symbol();
|
||||
|
||||
for arg_var in arg_vars {
|
||||
let arg_symbol = env.unique_symbol();
|
||||
|
||||
let loc_pattern =
|
||||
Located::at_zero(roc_can::pattern::Pattern::Identifier(arg_symbol));
|
||||
|
||||
let loc_expr = Located::at_zero(roc_can::expr::Expr::Var(arg_symbol));
|
||||
|
||||
loc_pattern_args.push((arg_var, loc_pattern));
|
||||
loc_expr_args.push((arg_var, loc_expr));
|
||||
}
|
||||
|
||||
let loc_body = Located::at_zero(roc_can::expr::Expr::Tag {
|
||||
variant_var: ret_var,
|
||||
name: tag_name,
|
||||
arguments: loc_expr_args,
|
||||
ext_var,
|
||||
});
|
||||
|
||||
let inserted = procs.insert_anonymous(
|
||||
env,
|
||||
proc_symbol,
|
||||
variant_var,
|
||||
loc_pattern_args,
|
||||
loc_body,
|
||||
CapturedSymbols::None,
|
||||
ret_var,
|
||||
layout_cache,
|
||||
);
|
||||
|
||||
match inserted {
|
||||
Ok(layout) => {
|
||||
return Stmt::Let(
|
||||
assigned,
|
||||
call_by_pointer(env, procs, proc_symbol, layout),
|
||||
layout,
|
||||
hole,
|
||||
);
|
||||
}
|
||||
Err(runtime_error) => {
|
||||
return Stmt::RuntimeError(env.arena.alloc(format!(
|
||||
"RuntimeError {} line {} {:?}",
|
||||
file!(),
|
||||
line!(),
|
||||
runtime_error,
|
||||
)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let res_variant = crate::layout::union_sorted_tags(env.arena, variant_var, env.subs);
|
||||
|
||||
let variant = match res_variant {
|
||||
|
@ -5893,6 +5987,20 @@ fn call_by_name<'a>(
|
|||
|
||||
// Register a pending_specialization for this function
|
||||
match layout_cache.from_var(env.arena, fn_var, env.subs) {
|
||||
Err(LayoutProblem::UnresolvedTypeVar(var)) => {
|
||||
let msg = format!(
|
||||
"Hit an unresolved type variable {:?} when creating a layout for {:?} (var {:?})",
|
||||
var, proc_name, fn_var
|
||||
);
|
||||
Stmt::RuntimeError(env.arena.alloc(msg))
|
||||
}
|
||||
Err(LayoutProblem::Erroneous) => {
|
||||
let msg = format!(
|
||||
"Hit an erroneous type when creating a layout for {:?}",
|
||||
proc_name
|
||||
);
|
||||
Stmt::RuntimeError(env.arena.alloc(msg))
|
||||
}
|
||||
Ok(layout) => {
|
||||
// Build the CallByName node
|
||||
let arena = env.arena;
|
||||
|
@ -6028,123 +6136,42 @@ fn call_by_name<'a>(
|
|||
"\n\n{:?}\n\n{:?}",
|
||||
full_layout, layout
|
||||
);
|
||||
let function_layout =
|
||||
FunctionLayouts::from_layout(env.arena, layout);
|
||||
|
||||
procs.specialized.remove(&(proc_name, full_layout));
|
||||
|
||||
procs
|
||||
.specialized
|
||||
.insert((proc_name, function_layout.full), Done(proc));
|
||||
|
||||
if field_symbols.is_empty() {
|
||||
debug_assert!(loc_args.is_empty());
|
||||
|
||||
// This happens when we return a function, e.g.
|
||||
//
|
||||
// foo = Num.add
|
||||
//
|
||||
// Even though the layout (and type) are functions,
|
||||
// there are no arguments. This confuses our IR,
|
||||
// and we have to fix it here.
|
||||
match full_layout {
|
||||
Layout::Closure(_, closure_layout, _) => {
|
||||
let call = self::Call {
|
||||
call_type: CallType::ByName {
|
||||
name: proc_name,
|
||||
ret_layout: function_layout.result,
|
||||
full_layout: function_layout.full,
|
||||
arg_layouts: function_layout.arguments,
|
||||
},
|
||||
arguments: field_symbols,
|
||||
};
|
||||
|
||||
// in the case of a closure specifically, we
|
||||
// have to create a custom layout, to make sure
|
||||
// the closure data is part of the layout
|
||||
let closure_struct_layout = Layout::Struct(
|
||||
env.arena.alloc([
|
||||
function_layout.full,
|
||||
closure_layout
|
||||
.as_block_of_memory_layout(),
|
||||
]),
|
||||
);
|
||||
|
||||
build_call(
|
||||
env,
|
||||
call,
|
||||
assigned,
|
||||
closure_struct_layout,
|
||||
hole,
|
||||
)
|
||||
}
|
||||
_ => {
|
||||
let call = self::Call {
|
||||
call_type: CallType::ByName {
|
||||
name: proc_name,
|
||||
ret_layout: function_layout.result,
|
||||
full_layout: function_layout.full,
|
||||
arg_layouts: function_layout.arguments,
|
||||
},
|
||||
arguments: field_symbols,
|
||||
};
|
||||
|
||||
build_call(
|
||||
env,
|
||||
call,
|
||||
assigned,
|
||||
function_layout.full,
|
||||
hole,
|
||||
)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
debug_assert_eq!(
|
||||
function_layout.arguments.len(),
|
||||
field_symbols.len(),
|
||||
"scroll up a bit for background"
|
||||
);
|
||||
let call = self::Call {
|
||||
call_type: CallType::ByName {
|
||||
name: proc_name,
|
||||
ret_layout: function_layout.result,
|
||||
full_layout: function_layout.full,
|
||||
arg_layouts: function_layout.arguments,
|
||||
},
|
||||
arguments: field_symbols,
|
||||
};
|
||||
|
||||
let iter = loc_args
|
||||
.into_iter()
|
||||
.rev()
|
||||
.zip(field_symbols.iter().rev());
|
||||
|
||||
let result = build_call(
|
||||
env,
|
||||
call,
|
||||
assigned,
|
||||
function_layout.result,
|
||||
hole,
|
||||
);
|
||||
|
||||
assign_to_symbols(
|
||||
env,
|
||||
procs,
|
||||
layout_cache,
|
||||
iter,
|
||||
result,
|
||||
)
|
||||
}
|
||||
call_specialized_proc(
|
||||
env,
|
||||
procs,
|
||||
proc_name,
|
||||
proc,
|
||||
layout,
|
||||
field_symbols,
|
||||
loc_args,
|
||||
layout_cache,
|
||||
assigned,
|
||||
hole,
|
||||
)
|
||||
}
|
||||
Err(error) => {
|
||||
let error_msg = env.arena.alloc(format!(
|
||||
"TODO generate a RuntimeError message for {:?}",
|
||||
error
|
||||
));
|
||||
Err(SpecializeFailure {
|
||||
attempted_layout,
|
||||
problem: _,
|
||||
}) => {
|
||||
let proc = generate_runtime_error_function(
|
||||
env,
|
||||
proc_name,
|
||||
attempted_layout,
|
||||
);
|
||||
|
||||
procs.runtime_errors.insert(proc_name, error_msg);
|
||||
|
||||
Stmt::RuntimeError(error_msg)
|
||||
call_specialized_proc(
|
||||
env,
|
||||
procs,
|
||||
proc_name,
|
||||
proc,
|
||||
layout,
|
||||
field_symbols,
|
||||
loc_args,
|
||||
layout_cache,
|
||||
assigned,
|
||||
hole,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -6191,33 +6218,104 @@ fn call_by_name<'a>(
|
|||
}
|
||||
|
||||
None => {
|
||||
// This must have been a runtime error.
|
||||
match procs.runtime_errors.get(&proc_name) {
|
||||
Some(error) => Stmt::RuntimeError(
|
||||
env.arena.alloc(format!("runtime error {:?}", error)),
|
||||
),
|
||||
None => unreachable!("Proc name {:?} is invalid", proc_name),
|
||||
}
|
||||
unreachable!("Proc name {:?} is invalid", proc_name)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(LayoutProblem::UnresolvedTypeVar(var)) => {
|
||||
let msg = format!(
|
||||
"Hit an unresolved type variable {:?} when creating a layout for {:?} (var {:?})",
|
||||
var, proc_name, fn_var
|
||||
);
|
||||
Stmt::RuntimeError(env.arena.alloc(msg))
|
||||
}
|
||||
Err(LayoutProblem::Erroneous) => {
|
||||
let msg = format!(
|
||||
"Hit an erroneous type when creating a layout for {:?}",
|
||||
proc_name
|
||||
);
|
||||
Stmt::RuntimeError(env.arena.alloc(msg))
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn call_specialized_proc<'a>(
|
||||
env: &mut Env<'a, '_>,
|
||||
procs: &mut Procs<'a>,
|
||||
proc_name: Symbol,
|
||||
proc: Proc<'a>,
|
||||
layout: Layout<'a>,
|
||||
field_symbols: &'a [Symbol],
|
||||
loc_args: std::vec::Vec<(Variable, Located<roc_can::expr::Expr>)>,
|
||||
layout_cache: &mut LayoutCache<'a>,
|
||||
assigned: Symbol,
|
||||
hole: &'a Stmt<'a>,
|
||||
) -> Stmt<'a> {
|
||||
let function_layout = FunctionLayouts::from_layout(env.arena, layout);
|
||||
|
||||
procs.specialized.remove(&(proc_name, layout));
|
||||
|
||||
procs
|
||||
.specialized
|
||||
.insert((proc_name, function_layout.full), Done(proc));
|
||||
|
||||
if field_symbols.is_empty() {
|
||||
debug_assert!(loc_args.is_empty());
|
||||
|
||||
// This happens when we return a function, e.g.
|
||||
//
|
||||
// foo = Num.add
|
||||
//
|
||||
// Even though the layout (and type) are functions,
|
||||
// there are no arguments. This confuses our IR,
|
||||
// and we have to fix it here.
|
||||
match layout {
|
||||
Layout::Closure(_, closure_layout, _) => {
|
||||
let call = self::Call {
|
||||
call_type: CallType::ByName {
|
||||
name: proc_name,
|
||||
ret_layout: function_layout.result,
|
||||
full_layout: function_layout.full,
|
||||
arg_layouts: function_layout.arguments,
|
||||
},
|
||||
arguments: field_symbols,
|
||||
};
|
||||
|
||||
// in the case of a closure specifically, we
|
||||
// have to create a custom layout, to make sure
|
||||
// the closure data is part of the layout
|
||||
let closure_struct_layout = Layout::Struct(env.arena.alloc([
|
||||
function_layout.full,
|
||||
closure_layout.as_block_of_memory_layout(),
|
||||
]));
|
||||
|
||||
build_call(env, call, assigned, closure_struct_layout, hole)
|
||||
}
|
||||
_ => {
|
||||
let call = self::Call {
|
||||
call_type: CallType::ByName {
|
||||
name: proc_name,
|
||||
ret_layout: function_layout.result,
|
||||
full_layout: function_layout.full,
|
||||
arg_layouts: function_layout.arguments,
|
||||
},
|
||||
arguments: field_symbols,
|
||||
};
|
||||
|
||||
build_call(env, call, assigned, function_layout.full, hole)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
debug_assert_eq!(
|
||||
function_layout.arguments.len(),
|
||||
field_symbols.len(),
|
||||
"scroll up a bit for background"
|
||||
);
|
||||
let call = self::Call {
|
||||
call_type: CallType::ByName {
|
||||
name: proc_name,
|
||||
ret_layout: function_layout.result,
|
||||
full_layout: function_layout.full,
|
||||
arg_layouts: function_layout.arguments,
|
||||
},
|
||||
arguments: field_symbols,
|
||||
};
|
||||
|
||||
let iter = loc_args.into_iter().rev().zip(field_symbols.iter().rev());
|
||||
|
||||
let result = build_call(env, call, assigned, function_layout.result, hole);
|
||||
|
||||
assign_to_symbols(env, procs, layout_cache, iter, result)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue