This commit is contained in:
Folkert 2021-01-28 15:39:25 +01:00
parent badce47838
commit c8f1bd98e0
2 changed files with 28 additions and 26 deletions

View file

@ -1359,7 +1359,7 @@ fn compile_test<'a>(
) -> Stmt<'a> { ) -> Stmt<'a> {
compile_test_help( compile_test_help(
env, env,
ChainBranchInfo::NeitherKnown, ConstructorKnown::Neither,
ret_layout, ret_layout,
stores, stores,
lhs, lhs,
@ -1369,9 +1369,10 @@ fn compile_test<'a>(
) )
} }
#[warn(clippy::too_many_arguments)]
fn compile_test_help<'a>( fn compile_test_help<'a>(
env: &mut Env<'a, '_>, env: &mut Env<'a, '_>,
branch_info: ChainBranchInfo<'a>, branch_info: ConstructorKnown<'a>,
ret_layout: Layout<'a>, ret_layout: Layout<'a>,
stores: bumpalo::collections::Vec<'a, (Symbol, Layout<'a>, Expr<'a>)>, stores: bumpalo::collections::Vec<'a, (Symbol, Layout<'a>, Expr<'a>)>,
lhs: Symbol, lhs: Symbol,
@ -1384,9 +1385,9 @@ fn compile_test_help<'a>(
let arena = env.arena; let arena = env.arena;
let (pass_info, fail_info) = { let (pass_info, fail_info) = {
use ChainBranchInfo::*; use ConstructorKnown::*;
match branch_info { match branch_info {
BothKnown { Both {
scrutinee, scrutinee,
layout, layout,
pass, pass,
@ -1406,7 +1407,7 @@ fn compile_test_help<'a>(
(pass_info, fail_info) (pass_info, fail_info)
} }
OnlyPassKnown { OnlyPass {
scrutinee, scrutinee,
layout, layout,
tag_id, tag_id,
@ -1420,7 +1421,7 @@ fn compile_test_help<'a>(
(pass_info, BranchInfo::None) (pass_info, BranchInfo::None)
} }
NeitherKnown => (BranchInfo::None, BranchInfo::None), Neither => (BranchInfo::None, BranchInfo::None),
} }
}; };
@ -1477,22 +1478,22 @@ fn compile_tests<'a>(
cond cond
} }
enum ChainBranchInfo<'a> { enum ConstructorKnown<'a> {
BothKnown { Both {
scrutinee: Symbol, scrutinee: Symbol,
layout: Layout<'a>, layout: Layout<'a>,
pass: u8, pass: u8,
fail: u8, fail: u8,
}, },
OnlyPassKnown { OnlyPass {
scrutinee: Symbol, scrutinee: Symbol,
layout: Layout<'a>, layout: Layout<'a>,
tag_id: u8, tag_id: u8,
}, },
NeitherKnown, Neither,
} }
impl<'a> ChainBranchInfo<'a> { impl<'a> ConstructorKnown<'a> {
fn from_test_chain( fn from_test_chain(
cond_symbol: Symbol, cond_symbol: Symbol,
cond_layout: &Layout<'a>, cond_layout: &Layout<'a>,
@ -1503,23 +1504,23 @@ impl<'a> ChainBranchInfo<'a> {
(Path::Empty, Test::IsCtor { tag_id, union, .. }) => { (Path::Empty, Test::IsCtor { tag_id, union, .. }) => {
if union.alternatives.len() == 2 { if union.alternatives.len() == 2 {
// excluded middle: we also know the tag_id in the fail branch // excluded middle: we also know the tag_id in the fail branch
ChainBranchInfo::BothKnown { ConstructorKnown::Both {
layout: cond_layout.clone(), layout: cond_layout.clone(),
scrutinee: cond_symbol, scrutinee: cond_symbol,
pass: *tag_id, pass: *tag_id,
fail: (*tag_id == 0) as u8, fail: (*tag_id == 0) as u8,
} }
} else { } else {
ChainBranchInfo::OnlyPassKnown { ConstructorKnown::OnlyPass {
layout: cond_layout.clone(), layout: cond_layout.clone(),
scrutinee: cond_symbol, scrutinee: cond_symbol,
tag_id: *tag_id, tag_id: *tag_id,
} }
} }
} }
_ => ChainBranchInfo::NeitherKnown, _ => ConstructorKnown::Neither,
}, },
_ => ChainBranchInfo::NeitherKnown, _ => ConstructorKnown::Neither,
} }
} }
} }
@ -1582,7 +1583,7 @@ fn decide_to_branching<'a>(
); );
let chain_branch_info = let chain_branch_info =
ChainBranchInfo::from_test_chain(cond_symbol, &cond_layout, &test_chain); ConstructorKnown::from_test_chain(cond_symbol, &cond_layout, &test_chain);
let (tests, guard) = stores_and_condition(env, cond_symbol, &cond_layout, test_chain); let (tests, guard) = stores_and_condition(env, cond_symbol, &cond_layout, test_chain);

View file

@ -236,8 +236,8 @@ fn work_for_constructor<'a>(
let field_aliases = env.alias_map.get(symbol); let field_aliases = env.alias_map.get(symbol);
match layout_for_constructor(env.arena, full_layout, constructor) { match layout_for_constructor(env.arena, full_layout, constructor) {
Unknown => return Unknown, Unknown => Unknown,
IsNull => return IsNull, IsNull => IsNull,
HasFields(cons_layout) => { HasFields(cons_layout) => {
// for each field, if it has refcounted content, check if it has an alias // for each field, if it has refcounted content, check if it has an alias
for (i, field_layout) in cons_layout.iter().enumerate() { for (i, field_layout) in cons_layout.iter().enumerate() {
@ -325,15 +325,16 @@ pub fn expand_and_cancel<'a>(env: &mut Env<'a, '_>, stmt: &'a Stmt<'a>) -> &'a S
env.layout_map.insert(symbol, layout.clone()); env.layout_map.insert(symbol, layout.clone());
match expr { if let Expr::AccessAtIndex {
Expr::AccessAtIndex { structure, index, ..
structure, index, .. } = expr
} => { {
let entry = env.alias_map.entry(*structure).or_insert(MutMap::default()); let entry = env
.alias_map
.entry(*structure)
.or_insert_with(MutMap::default);
entry.insert(*index, symbol); entry.insert(*index, symbol);
}
_ => {}
} }
let cont = expand_and_cancel(env, cont); let cont = expand_and_cancel(env, cont);