mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-01 07:41:12 +00:00
Merge remote-tracking branch 'origin/trunk' into gen-equality
This commit is contained in:
commit
821df8bff8
4 changed files with 86 additions and 22 deletions
|
@ -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,25 +412,38 @@ 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 {
|
||||||
structure, index, ..
|
Expr::AccessAtIndex {
|
||||||
} = &expr
|
structure, index, ..
|
||||||
{
|
} => {
|
||||||
let entry = env
|
let entry = env
|
||||||
.alias_map
|
.alias_map
|
||||||
.entry(*structure)
|
.entry(*structure)
|
||||||
.or_insert_with(MutMap::default);
|
.or_insert_with(MutMap::default);
|
||||||
|
|
||||||
entry.insert(*index, symbol);
|
entry.insert(*index, symbol);
|
||||||
|
|
||||||
new_cont = expand_and_cancel(env, cont);
|
new_cont = expand_and_cancel(env, cont);
|
||||||
|
|
||||||
// make sure to remove the alias, so other branches don't use it by accident
|
// make sure to remove the alias, so other branches don't use it by accident
|
||||||
env.alias_map
|
env.alias_map
|
||||||
.get_mut(structure)
|
.get_mut(structure)
|
||||||
.and_then(|map| map.remove(index));
|
.and_then(|map| map.remove(index));
|
||||||
} else {
|
}
|
||||||
new_cont = expand_and_cancel(env, cont);
|
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 {
|
||||||
|
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);
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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> {
|
||||||
|
|
|
@ -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;
|
||||||
"#
|
"#
|
||||||
),
|
),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue