Merge remote-tracking branch 'origin/trunk' into gen-equality

This commit is contained in:
Folkert 2021-02-14 03:44:31 +01:00
commit 821df8bff8
4 changed files with 86 additions and 22 deletions

View file

@ -157,6 +157,16 @@ impl<'a, 'i> Env<'a, 'i> {
} }
} }
fn insert_struct_info(&mut self, symbol: Symbol, fields: &'a [Layout<'a>]) {
self.constructor_map.insert(symbol, 0);
self.layout_map.insert(symbol, Layout::Struct(fields));
}
fn remove_struct_info(&mut self, symbol: Symbol) {
self.constructor_map.remove(&symbol);
self.layout_map.remove(&symbol);
}
pub fn unique_symbol(&mut self) -> Symbol { pub fn unique_symbol(&mut self) -> Symbol {
let ident_id = self.ident_ids.gen_unique(); let ident_id = self.ident_ids.gen_unique();
@ -213,6 +223,10 @@ fn layout_for_constructor<'a>(
} }
} }
} }
Struct(fields) => {
debug_assert_eq!(constructor, 0);
HasFields(fields)
}
_ => unreachable!(), _ => unreachable!(),
} }
} }
@ -322,7 +336,39 @@ enum ConstructorLayout<T> {
Unknown, Unknown,
} }
pub fn expand_and_cancel<'a>(env: &mut Env<'a, '_>, stmt: &'a Stmt<'a>) -> &'a Stmt<'a> { pub fn expand_and_cancel_proc<'a>(
env: &mut Env<'a, '_>,
stmt: &'a Stmt<'a>,
arguments: &'a [(Layout<'a>, Symbol)],
) -> &'a Stmt<'a> {
let mut introduced = Vec::new_in(env.arena);
for (layout, symbol) in arguments {
match layout {
Layout::Struct(fields) => {
env.insert_struct_info(*symbol, fields);
introduced.push(*symbol);
}
Layout::Closure(_, closure_layout, _) => {
if let Layout::Struct(fields) = closure_layout.layout {
env.insert_struct_info(*symbol, fields);
}
}
_ => {}
}
}
let result = expand_and_cancel(env, stmt);
for symbol in introduced {
env.remove_struct_info(symbol);
}
result
}
fn expand_and_cancel<'a>(env: &mut Env<'a, '_>, stmt: &'a Stmt<'a>) -> &'a Stmt<'a> {
use Stmt::*; use Stmt::*;
let mut deferred_default = Deferred { let mut deferred_default = Deferred {
@ -351,7 +397,7 @@ pub fn expand_and_cancel<'a>(env: &mut Env<'a, '_>, stmt: &'a Stmt<'a>) -> &'a S
// prevent long chains of `Let`s from blowing the stack // prevent long chains of `Let`s from blowing the stack
let mut literal_stack = Vec::new_in(env.arena); let mut literal_stack = Vec::new_in(env.arena);
while !matches!(&expr, Expr::AccessAtIndex { .. } ) { while !matches!(&expr, Expr::AccessAtIndex { .. } | Expr::Struct(_)) {
if let Stmt::Let(symbol1, expr1, layout1, cont1) = cont { if let Stmt::Let(symbol1, expr1, layout1, cont1) = cont {
literal_stack.push((symbol, expr.clone(), layout.clone())); literal_stack.push((symbol, expr.clone(), layout.clone()));
@ -366,10 +412,10 @@ pub fn expand_and_cancel<'a>(env: &mut Env<'a, '_>, stmt: &'a Stmt<'a>) -> &'a S
let new_cont; let new_cont;
if let Expr::AccessAtIndex { match &expr {
Expr::AccessAtIndex {
structure, index, .. structure, index, ..
} = &expr } => {
{
let entry = env let entry = env
.alias_map .alias_map
.entry(*structure) .entry(*structure)
@ -383,9 +429,22 @@ pub fn expand_and_cancel<'a>(env: &mut Env<'a, '_>, stmt: &'a Stmt<'a>) -> &'a S
env.alias_map env.alias_map
.get_mut(structure) .get_mut(structure)
.and_then(|map| map.remove(index)); .and_then(|map| map.remove(index));
}
Expr::Struct(_) => {
if let Layout::Struct(fields) = layout {
env.insert_struct_info(symbol, fields);
new_cont = expand_and_cancel(env, cont);
env.remove_struct_info(symbol);
} else { } else {
new_cont = expand_and_cancel(env, cont); new_cont = expand_and_cancel(env, cont);
} }
}
_ => {
new_cont = expand_and_cancel(env, cont);
}
}
let stmt = Let(symbol, expr.clone(), layout.clone(), new_cont); let stmt = Let(symbol, expr.clone(), layout.clone(), new_cont);
let mut stmt = &*env.arena.alloc(stmt); let mut stmt = &*env.arena.alloc(stmt);

View file

@ -205,7 +205,11 @@ impl<'a> Proc<'a> {
}; };
for (_, proc) in procs.iter_mut() { for (_, proc) in procs.iter_mut() {
let b = expand_rc::expand_and_cancel(&mut env, arena.alloc(proc.body.clone())); let b = expand_rc::expand_and_cancel_proc(
&mut env,
arena.alloc(proc.body.clone()),
proc.args,
);
proc.body = b.clone(); proc.body = b.clone();
} }
} }

View file

@ -70,7 +70,9 @@ pub struct ClosureLayout<'a> {
/// the vec is likely to be small, so linear search is fine /// the vec is likely to be small, so linear search is fine
captured: &'a [(TagName, &'a [Layout<'a>])], captured: &'a [(TagName, &'a [Layout<'a>])],
layout: &'a Layout<'a>, /// use with care; there is some stuff happening here re. unwrapping
/// one-element records that might cause issues
pub layout: &'a Layout<'a>,
} }
impl<'a> ClosureLayout<'a> { impl<'a> ClosureLayout<'a> {

View file

@ -949,8 +949,7 @@ mod test_mono {
let Test.5 = 3.14f64; let Test.5 = 3.14f64;
let Test.3 = Struct {Test.4, Test.5}; let Test.3 = Struct {Test.4, Test.5};
let Test.1 = Index 0 Test.3; let Test.1 = Index 0 Test.3;
inc Test.1; decref Test.3;
dec Test.3;
ret Test.1; ret Test.1;
"# "#
), ),