use union layout in mono patterns

This commit is contained in:
Folkert 2021-06-20 18:12:18 +02:00
parent 61c9de91dc
commit bc8bd95b3d
2 changed files with 77 additions and 78 deletions

View file

@ -220,8 +220,7 @@ fn flatten<'a>(
} if union.alternatives.len() == 1 } if union.alternatives.len() == 1
&& !matches!( && !matches!(
layout, layout,
Layout::Union(UnionLayout::NullableWrapped { .. }) UnionLayout::NullableWrapped { .. } | UnionLayout::NullableUnwrapped { .. }
| Layout::Union(UnionLayout::NullableUnwrapped { .. })
) => ) =>
{ {
// TODO ^ do we need to check that guard.is_none() here? // TODO ^ do we need to check that guard.is_none() here?
@ -633,12 +632,9 @@ fn to_relevant_branch_help<'a>(
debug_assert_eq!(tag_id, *test_id); debug_assert_eq!(tag_id, *test_id);
// the test matches the constructor of this pattern // the test matches the constructor of this pattern
match layout {
match Wrapped::opt_from_layout(&layout) { UnionLayout::NonRecursive([[Layout::Struct([_])]]) => {
None => todo!(), // a one-element record equivalent
Some(wrapped) => {
match wrapped {
Wrapped::SingleElementRecord => {
// Theory: Unbox doesn't have any value for us // Theory: Unbox doesn't have any value for us
debug_assert_eq!(arguments.len(), 1); debug_assert_eq!(arguments.len(), 1);
let arg = arguments[0].clone(); let arg = arguments[0].clone();
@ -649,35 +645,41 @@ fn to_relevant_branch_help<'a>(
start.extend(end); start.extend(end);
} }
} }
Wrapped::RecordOrSingleTagUnion | Wrapped::LikeARoseTree => { UnionLayout::NonRecursive([_]) | UnionLayout::NonNullableUnwrapped(_) => {
let sub_positions = arguments.into_iter().enumerate().map( let sub_positions =
|(index, (pattern, _))| { arguments
.into_iter()
.enumerate()
.map(|(index, (pattern, _))| {
let mut new_path = path.to_vec(); let mut new_path = path.to_vec();
new_path.push(PathInstruction { new_path.push(PathInstruction {
index: index as u64, index: index as u64,
tag_id, tag_id,
}); });
(new_path, Guard::NoGuard, pattern) (new_path, Guard::NoGuard, pattern)
}, });
);
start.extend(sub_positions); start.extend(sub_positions);
start.extend(end); start.extend(end);
} }
Wrapped::MultiTagUnion => { UnionLayout::NonRecursive(_)
let sub_positions = arguments.into_iter().enumerate().map( | UnionLayout::Recursive(_)
|(index, (pattern, _))| { | UnionLayout::NullableWrapped { .. }
| UnionLayout::NullableUnwrapped { .. } => {
let sub_positions =
arguments
.into_iter()
.enumerate()
.map(|(index, (pattern, _))| {
let mut new_path = path.to_vec(); let mut new_path = path.to_vec();
new_path.push(PathInstruction { new_path.push(PathInstruction {
index: 1 + index as u64, index: 1 + index as u64,
tag_id, tag_id,
}); });
(new_path, Guard::NoGuard, pattern) (new_path, Guard::NoGuard, pattern)
}, });
);
start.extend(sub_positions); start.extend(sub_positions);
start.extend(end); start.extend(end);
} }
Wrapped::EmptyRecord => todo!(),
} }
Some(Branch { Some(Branch {
@ -685,8 +687,6 @@ fn to_relevant_branch_help<'a>(
patterns: start, patterns: start,
}) })
} }
}
}
_ => None, _ => None,
} }
} }

View file

@ -5586,22 +5586,6 @@ fn store_pattern_help<'a>(
| StrLiteral(_) => { | StrLiteral(_) => {
return StorePattern::NotProductive(stmt); return StorePattern::NotProductive(stmt);
} }
AppliedTag {
arguments, layout, ..
} => {
let wrapped = Wrapped::from_layout(layout);
return store_tag_pattern(
env,
procs,
layout_cache,
outer_symbol,
layout,
&arguments,
wrapped,
stmt,
);
}
NewtypeDestructure { arguments, .. } => { NewtypeDestructure { arguments, .. } => {
let mut fields = Vec::with_capacity_in(arguments.len(), env.arena); let mut fields = Vec::with_capacity_in(arguments.len(), env.arena);
fields.extend(arguments.iter().map(|x| x.1)); fields.extend(arguments.iter().map(|x| x.1));
@ -5621,6 +5605,23 @@ fn store_pattern_help<'a>(
stmt, stmt,
); );
} }
AppliedTag {
arguments, layout, ..
} => {
let union_layout = Layout::Union(*layout);
let wrapped = Wrapped::from_layout(&union_layout);
return store_tag_pattern(
env,
procs,
layout_cache,
outer_symbol,
&union_layout,
&arguments,
wrapped,
stmt,
);
}
RecordDestructure(destructs, sorted_fields) => { RecordDestructure(destructs, sorted_fields) => {
let mut is_productive = false; let mut is_productive = false;
for (index, destruct) in destructs.iter().enumerate().rev() { for (index, destruct) in destructs.iter().enumerate().rev() {
@ -6781,7 +6782,7 @@ pub enum Pattern<'a> {
tag_name: TagName, tag_name: TagName,
tag_id: u8, tag_id: u8,
arguments: Vec<'a, (Pattern<'a>, Layout<'a>)>, arguments: Vec<'a, (Pattern<'a>, Layout<'a>)>,
layout: Layout<'a>, layout: UnionLayout<'a>,
union: crate::exhaustive::Union, union: crate::exhaustive::Union,
}, },
} }
@ -7049,8 +7050,7 @@ fn from_can_pattern_help<'a>(
temp temp
}; };
let layout = let layout = UnionLayout::NonRecursive(layouts.into_bump_slice());
Layout::Union(UnionLayout::NonRecursive(layouts.into_bump_slice()));
Pattern::AppliedTag { Pattern::AppliedTag {
tag_name: tag_name.clone(), tag_name: tag_name.clone(),
@ -7108,8 +7108,7 @@ fn from_can_pattern_help<'a>(
}; };
debug_assert!(layouts.len() > 1); debug_assert!(layouts.len() > 1);
let layout = let layout = UnionLayout::Recursive(layouts.into_bump_slice());
Layout::Union(UnionLayout::Recursive(layouts.into_bump_slice()));
Pattern::AppliedTag { Pattern::AppliedTag {
tag_name: tag_name.clone(), tag_name: tag_name.clone(),
@ -7154,7 +7153,7 @@ fn from_can_pattern_help<'a>(
)); ));
} }
let layout = Layout::Union(UnionLayout::NonNullableUnwrapped(fields)); let layout = UnionLayout::NonNullableUnwrapped(fields);
Pattern::AppliedTag { Pattern::AppliedTag {
tag_name: tag_name.clone(), tag_name: tag_name.clone(),
@ -7239,10 +7238,10 @@ fn from_can_pattern_help<'a>(
temp temp
}; };
let layout = Layout::Union(UnionLayout::NullableWrapped { let layout = UnionLayout::NullableWrapped {
nullable_id, nullable_id,
other_tags: layouts.into_bump_slice(), other_tags: layouts.into_bump_slice(),
}); };
Pattern::AppliedTag { Pattern::AppliedTag {
tag_name: tag_name.clone(), tag_name: tag_name.clone(),
@ -7300,10 +7299,10 @@ fn from_can_pattern_help<'a>(
)); ));
} }
let layout = Layout::Union(UnionLayout::NullableUnwrapped { let layout = UnionLayout::NullableUnwrapped {
nullable_id, nullable_id,
other_fields, other_fields,
}); };
Pattern::AppliedTag { Pattern::AppliedTag {
tag_name: tag_name.clone(), tag_name: tag_name.clone(),