mirror of
https://github.com/roc-lang/roc.git
synced 2025-08-02 19:32:17 +00:00
Pass interner through to debug proc layouts misisng in param map
This commit is contained in:
parent
e5c3376e90
commit
f7aa7e734d
2 changed files with 92 additions and 40 deletions
|
@ -100,8 +100,14 @@ pub fn infer_borrow<'a>(
|
||||||
// host-exposed functions must always own their arguments.
|
// host-exposed functions must always own their arguments.
|
||||||
let is_host_exposed = host_exposed_procs.contains(&key.0);
|
let is_host_exposed = host_exposed_procs.contains(&key.0);
|
||||||
|
|
||||||
let param_offset = param_map.get_param_offset(key.0, key.1);
|
let param_offset = param_map.get_param_offset(interner, key.0, key.1);
|
||||||
env.collect_proc(&mut param_map, proc, param_offset, is_host_exposed);
|
env.collect_proc(
|
||||||
|
interner,
|
||||||
|
&mut param_map,
|
||||||
|
proc,
|
||||||
|
param_offset,
|
||||||
|
is_host_exposed,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if !env.modified {
|
if !env.modified {
|
||||||
|
@ -167,6 +173,7 @@ impl<'a> DeclarationToIndex<'a> {
|
||||||
|
|
||||||
fn get_param_offset(
|
fn get_param_offset(
|
||||||
&self,
|
&self,
|
||||||
|
interner: &STLayoutInterner<'a>,
|
||||||
needle_symbol: Symbol,
|
needle_symbol: Symbol,
|
||||||
needle_layout: ProcLayout<'a>,
|
needle_layout: ProcLayout<'a>,
|
||||||
) -> ParamOffset {
|
) -> ParamOffset {
|
||||||
|
@ -181,12 +188,14 @@ impl<'a> DeclarationToIndex<'a> {
|
||||||
.elements
|
.elements
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|(Declaration { symbol, layout }, _)| {
|
.filter_map(|(Declaration { symbol, layout }, _)| {
|
||||||
(*symbol == needle_symbol).then_some(layout)
|
(*symbol == needle_symbol)
|
||||||
|
.then_some(layout)
|
||||||
|
.map(|l| l.dbg_deep(interner))
|
||||||
})
|
})
|
||||||
.collect::<std::vec::Vec<_>>();
|
.collect::<std::vec::Vec<_>>();
|
||||||
unreachable!(
|
unreachable!(
|
||||||
"symbol/layout {:?} {:#?} combo must be in DeclarationToIndex\nHowever {} similar layouts were found:\n{:#?}",
|
"symbol/layout {:?} {:#?} combo must be in DeclarationToIndex\nHowever {} similar layouts were found:\n{:#?}",
|
||||||
needle_symbol, needle_layout, similar.len(), similar
|
needle_symbol, needle_layout.dbg_deep(interner), similar.len(), similar,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -206,13 +215,24 @@ pub struct ParamMap<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> ParamMap<'a> {
|
impl<'a> ParamMap<'a> {
|
||||||
pub fn get_param_offset(&self, symbol: Symbol, layout: ProcLayout<'a>) -> ParamOffset {
|
pub fn get_param_offset(
|
||||||
self.declaration_to_index.get_param_offset(symbol, layout)
|
&self,
|
||||||
|
interner: &STLayoutInterner<'a>,
|
||||||
|
symbol: Symbol,
|
||||||
|
layout: ProcLayout<'a>,
|
||||||
|
) -> ParamOffset {
|
||||||
|
self.declaration_to_index
|
||||||
|
.get_param_offset(interner, symbol, layout)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_symbol(&self, symbol: Symbol, layout: ProcLayout<'a>) -> Option<&[Param<'a>]> {
|
pub fn get_symbol(
|
||||||
|
&self,
|
||||||
|
interner: &STLayoutInterner<'a>,
|
||||||
|
symbol: Symbol,
|
||||||
|
layout: ProcLayout<'a>,
|
||||||
|
) -> Option<&[Param<'a>]> {
|
||||||
// let index: usize = self.declaration_to_index[&(symbol, layout)].into();
|
// let index: usize = self.declaration_to_index[&(symbol, layout)].into();
|
||||||
let index: usize = self.get_param_offset(symbol, layout).into();
|
let index: usize = self.get_param_offset(interner, symbol, layout).into();
|
||||||
|
|
||||||
self.declarations.get(index..index + layout.arguments.len())
|
self.declarations.get(index..index + layout.arguments.len())
|
||||||
}
|
}
|
||||||
|
@ -292,7 +312,7 @@ impl<'a> ParamMap<'a> {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let index: usize = self.get_param_offset(key.0, key.1).into();
|
let index: usize = self.get_param_offset(interner, key.0, key.1).into();
|
||||||
|
|
||||||
for (i, param) in Self::init_borrow_args(arena, interner, proc.args)
|
for (i, param) in Self::init_borrow_args(arena, interner, proc.args)
|
||||||
.iter()
|
.iter()
|
||||||
|
@ -312,7 +332,7 @@ impl<'a> ParamMap<'a> {
|
||||||
proc: &Proc<'a>,
|
proc: &Proc<'a>,
|
||||||
key: (Symbol, ProcLayout<'a>),
|
key: (Symbol, ProcLayout<'a>),
|
||||||
) {
|
) {
|
||||||
let index: usize = self.get_param_offset(key.0, key.1).into();
|
let index: usize = self.get_param_offset(interner, key.0, key.1).into();
|
||||||
|
|
||||||
for (i, param) in Self::init_borrow_args_always_owned(arena, proc.args)
|
for (i, param) in Self::init_borrow_args_always_owned(arena, proc.args)
|
||||||
.iter()
|
.iter()
|
||||||
|
@ -534,7 +554,13 @@ impl<'a> BorrowInfState<'a> {
|
||||||
///
|
///
|
||||||
/// and determines whether z and which of the symbols used in e
|
/// and determines whether z and which of the symbols used in e
|
||||||
/// must be taken as owned parameters
|
/// must be taken as owned parameters
|
||||||
fn collect_call(&mut self, param_map: &mut ParamMap<'a>, z: Symbol, e: &crate::ir::Call<'a>) {
|
fn collect_call(
|
||||||
|
&mut self,
|
||||||
|
interner: &STLayoutInterner<'a>,
|
||||||
|
param_map: &mut ParamMap<'a>,
|
||||||
|
z: Symbol,
|
||||||
|
e: &crate::ir::Call<'a>,
|
||||||
|
) {
|
||||||
use crate::ir::CallType::*;
|
use crate::ir::CallType::*;
|
||||||
|
|
||||||
let crate::ir::Call {
|
let crate::ir::Call {
|
||||||
|
@ -553,7 +579,7 @@ impl<'a> BorrowInfState<'a> {
|
||||||
|
|
||||||
// get the borrow signature of the applied function
|
// get the borrow signature of the applied function
|
||||||
let ps = param_map
|
let ps = param_map
|
||||||
.get_symbol(name.name(), top_level)
|
.get_symbol(interner, name.name(), top_level)
|
||||||
.expect("function is defined");
|
.expect("function is defined");
|
||||||
|
|
||||||
// the return value will be owned
|
// the return value will be owned
|
||||||
|
@ -595,11 +621,14 @@ impl<'a> BorrowInfState<'a> {
|
||||||
niche: passed_function.name.niche(),
|
niche: passed_function.name.niche(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let function_ps =
|
let function_ps = match param_map.get_symbol(
|
||||||
match param_map.get_symbol(passed_function.name.name(), closure_layout) {
|
interner,
|
||||||
Some(function_ps) => function_ps,
|
passed_function.name.name(),
|
||||||
None => unreachable!(),
|
closure_layout,
|
||||||
};
|
) {
|
||||||
|
Some(function_ps) => function_ps,
|
||||||
|
None => unreachable!(),
|
||||||
|
};
|
||||||
|
|
||||||
match op {
|
match op {
|
||||||
ListMap { xs } => {
|
ListMap { xs } => {
|
||||||
|
@ -671,7 +700,13 @@ impl<'a> BorrowInfState<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn collect_expr(&mut self, param_map: &mut ParamMap<'a>, z: Symbol, e: &Expr<'a>) {
|
fn collect_expr(
|
||||||
|
&mut self,
|
||||||
|
interner: &STLayoutInterner<'a>,
|
||||||
|
param_map: &mut ParamMap<'a>,
|
||||||
|
z: Symbol,
|
||||||
|
e: &Expr<'a>,
|
||||||
|
) {
|
||||||
use Expr::*;
|
use Expr::*;
|
||||||
|
|
||||||
match e {
|
match e {
|
||||||
|
@ -724,7 +759,7 @@ impl<'a> BorrowInfState<'a> {
|
||||||
self.own_var(z);
|
self.own_var(z);
|
||||||
}
|
}
|
||||||
|
|
||||||
Call(call) => self.collect_call(param_map, z, call),
|
Call(call) => self.collect_call(interner, param_map, z, call),
|
||||||
|
|
||||||
Literal(_) | RuntimeErrorFunction(_) => {}
|
Literal(_) | RuntimeErrorFunction(_) => {}
|
||||||
|
|
||||||
|
@ -757,6 +792,7 @@ impl<'a> BorrowInfState<'a> {
|
||||||
#[allow(clippy::many_single_char_names)]
|
#[allow(clippy::many_single_char_names)]
|
||||||
fn preserve_tail_call(
|
fn preserve_tail_call(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
interner: &STLayoutInterner<'a>,
|
||||||
param_map: &mut ParamMap<'a>,
|
param_map: &mut ParamMap<'a>,
|
||||||
x: Symbol,
|
x: Symbol,
|
||||||
v: &Expr<'a>,
|
v: &Expr<'a>,
|
||||||
|
@ -782,7 +818,7 @@ impl<'a> BorrowInfState<'a> {
|
||||||
if self.current_proc == g.name() && x == *z {
|
if self.current_proc == g.name() && x == *z {
|
||||||
// anonymous functions (for which the ps may not be known)
|
// anonymous functions (for which the ps may not be known)
|
||||||
// can never be tail-recursive, so this is fine
|
// can never be tail-recursive, so this is fine
|
||||||
if let Some(ps) = param_map.get_symbol(g.name(), top_level) {
|
if let Some(ps) = param_map.get_symbol(interner, g.name(), top_level) {
|
||||||
self.own_params_using_args(ys, ps)
|
self.own_params_using_args(ys, ps)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -801,7 +837,12 @@ impl<'a> BorrowInfState<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn collect_stmt(&mut self, param_map: &mut ParamMap<'a>, stmt: &Stmt<'a>) {
|
fn collect_stmt(
|
||||||
|
&mut self,
|
||||||
|
interner: &STLayoutInterner<'a>,
|
||||||
|
param_map: &mut ParamMap<'a>,
|
||||||
|
stmt: &Stmt<'a>,
|
||||||
|
) {
|
||||||
use Stmt::*;
|
use Stmt::*;
|
||||||
|
|
||||||
match stmt {
|
match stmt {
|
||||||
|
@ -813,11 +854,11 @@ impl<'a> BorrowInfState<'a> {
|
||||||
} => {
|
} => {
|
||||||
let old = self.param_set.clone();
|
let old = self.param_set.clone();
|
||||||
self.update_param_set(ys);
|
self.update_param_set(ys);
|
||||||
self.collect_stmt(param_map, v);
|
self.collect_stmt(interner, param_map, v);
|
||||||
self.param_set = old;
|
self.param_set = old;
|
||||||
self.update_param_map_join_point(param_map, *j);
|
self.update_param_map_join_point(param_map, *j);
|
||||||
|
|
||||||
self.collect_stmt(param_map, b);
|
self.collect_stmt(interner, param_map, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
Let(x, v, _, mut b) => {
|
Let(x, v, _, mut b) => {
|
||||||
|
@ -830,17 +871,17 @@ impl<'a> BorrowInfState<'a> {
|
||||||
stack.push((*symbol, expr));
|
stack.push((*symbol, expr));
|
||||||
}
|
}
|
||||||
|
|
||||||
self.collect_stmt(param_map, b);
|
self.collect_stmt(interner, param_map, b);
|
||||||
|
|
||||||
let mut it = stack.into_iter().rev();
|
let mut it = stack.into_iter().rev();
|
||||||
|
|
||||||
// collect the final expr, and see if we need to preserve a tail call
|
// collect the final expr, and see if we need to preserve a tail call
|
||||||
let (x, v) = it.next().unwrap();
|
let (x, v) = it.next().unwrap();
|
||||||
self.collect_expr(param_map, x, v);
|
self.collect_expr(interner, param_map, x, v);
|
||||||
self.preserve_tail_call(param_map, x, v, b);
|
self.preserve_tail_call(interner, param_map, x, v, b);
|
||||||
|
|
||||||
for (x, v) in it {
|
for (x, v) in it {
|
||||||
self.collect_expr(param_map, x, v);
|
self.collect_expr(interner, param_map, x, v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -859,21 +900,21 @@ impl<'a> BorrowInfState<'a> {
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
for (_, _, b) in branches.iter() {
|
for (_, _, b) in branches.iter() {
|
||||||
self.collect_stmt(param_map, b);
|
self.collect_stmt(interner, param_map, b);
|
||||||
}
|
}
|
||||||
self.collect_stmt(param_map, default_branch.1);
|
self.collect_stmt(interner, param_map, default_branch.1);
|
||||||
}
|
}
|
||||||
|
|
||||||
Dbg { remainder, .. } => {
|
Dbg { remainder, .. } => {
|
||||||
self.collect_stmt(param_map, remainder);
|
self.collect_stmt(interner, param_map, remainder);
|
||||||
}
|
}
|
||||||
|
|
||||||
Expect { remainder, .. } => {
|
Expect { remainder, .. } => {
|
||||||
self.collect_stmt(param_map, remainder);
|
self.collect_stmt(interner, param_map, remainder);
|
||||||
}
|
}
|
||||||
|
|
||||||
ExpectFx { remainder, .. } => {
|
ExpectFx { remainder, .. } => {
|
||||||
self.collect_stmt(param_map, remainder);
|
self.collect_stmt(interner, param_map, remainder);
|
||||||
}
|
}
|
||||||
|
|
||||||
Refcounting(_, _) => unreachable!("these have not been introduced yet"),
|
Refcounting(_, _) => unreachable!("these have not been introduced yet"),
|
||||||
|
@ -891,6 +932,7 @@ impl<'a> BorrowInfState<'a> {
|
||||||
|
|
||||||
fn collect_proc(
|
fn collect_proc(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
interner: &STLayoutInterner<'a>,
|
||||||
param_map: &mut ParamMap<'a>,
|
param_map: &mut ParamMap<'a>,
|
||||||
proc: &Proc<'a>,
|
proc: &Proc<'a>,
|
||||||
param_offset: ParamOffset,
|
param_offset: ParamOffset,
|
||||||
|
@ -912,7 +954,7 @@ impl<'a> BorrowInfState<'a> {
|
||||||
owned_entry.extend(params.iter().map(|p| p.symbol));
|
owned_entry.extend(params.iter().map(|p| p.symbol));
|
||||||
}
|
}
|
||||||
|
|
||||||
self.collect_stmt(param_map, &proc.body);
|
self.collect_stmt(interner, param_map, &proc.body);
|
||||||
self.update_param_map_declaration(param_map, param_offset, proc.args.len());
|
self.update_param_map_declaration(param_map, param_offset, proc.args.len());
|
||||||
|
|
||||||
self.param_set = old;
|
self.param_set = old;
|
||||||
|
|
|
@ -605,7 +605,7 @@ impl<'a, 'i> Context<'a, 'i> {
|
||||||
// get the borrow signature
|
// get the borrow signature
|
||||||
let ps = self
|
let ps = self
|
||||||
.param_map
|
.param_map
|
||||||
.get_symbol(name.name(), top_level)
|
.get_symbol(self.layout_interner, name.name(), top_level)
|
||||||
.expect("function is defined");
|
.expect("function is defined");
|
||||||
|
|
||||||
let v = Expr::Call(crate::ir::Call {
|
let v = Expr::Call(crate::ir::Call {
|
||||||
|
@ -653,10 +653,11 @@ impl<'a, 'i> Context<'a, 'i> {
|
||||||
niche: passed_function.name.niche(),
|
niche: passed_function.name.niche(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let function_ps = match self
|
let function_ps = match self.param_map.get_symbol(
|
||||||
.param_map
|
self.layout_interner,
|
||||||
.get_symbol(passed_function.name.name(), function_layout)
|
passed_function.name.name(),
|
||||||
{
|
function_layout,
|
||||||
|
) {
|
||||||
Some(function_ps) => function_ps,
|
Some(function_ps) => function_ps,
|
||||||
None => unreachable!(),
|
None => unreachable!(),
|
||||||
};
|
};
|
||||||
|
@ -1510,19 +1511,28 @@ pub fn visit_procs<'a, 'i>(
|
||||||
};
|
};
|
||||||
|
|
||||||
for (key, proc) in procs.iter_mut() {
|
for (key, proc) in procs.iter_mut() {
|
||||||
visit_proc(arena, &mut codegen, param_map, &ctx, proc, key.1);
|
visit_proc(
|
||||||
|
arena,
|
||||||
|
layout_interner,
|
||||||
|
&mut codegen,
|
||||||
|
param_map,
|
||||||
|
&ctx,
|
||||||
|
proc,
|
||||||
|
key.1,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_proc<'a, 'i>(
|
fn visit_proc<'a, 'i>(
|
||||||
arena: &'a Bump,
|
arena: &'a Bump,
|
||||||
|
interner: &STLayoutInterner<'a>,
|
||||||
codegen: &mut CodegenTools<'i>,
|
codegen: &mut CodegenTools<'i>,
|
||||||
param_map: &'a ParamMap<'a>,
|
param_map: &'a ParamMap<'a>,
|
||||||
ctx: &Context<'a, 'i>,
|
ctx: &Context<'a, 'i>,
|
||||||
proc: &mut Proc<'a>,
|
proc: &mut Proc<'a>,
|
||||||
layout: ProcLayout<'a>,
|
layout: ProcLayout<'a>,
|
||||||
) {
|
) {
|
||||||
let params = match param_map.get_symbol(proc.name.name(), layout) {
|
let params = match param_map.get_symbol(interner, proc.name.name(), layout) {
|
||||||
Some(slice) => slice,
|
Some(slice) => slice,
|
||||||
None => Vec::from_iter_in(
|
None => Vec::from_iter_in(
|
||||||
proc.args.iter().cloned().map(|(layout, symbol)| Param {
|
proc.args.iter().cloned().map(|(layout, symbol)| Param {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue