mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-28 06:14:46 +00:00
don't unroll recursive layouts
This commit is contained in:
parent
ee67ee546a
commit
5250e930aa
2 changed files with 30 additions and 12 deletions
|
@ -1508,6 +1508,18 @@ fn get_recursion_var(subs: &Subs, var: Variable) -> Option<Variable> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn is_recursive_tag_union(layout: &Layout) -> bool {
|
||||||
|
match layout {
|
||||||
|
Layout::Union(
|
||||||
|
UnionLayout::NullableUnwrapped { .. }
|
||||||
|
| UnionLayout::Recursive(_)
|
||||||
|
| UnionLayout::NullableWrapped { .. }
|
||||||
|
| UnionLayout::NonNullableUnwrapped { .. },
|
||||||
|
) => true,
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn union_sorted_tags_help<'a>(
|
pub fn union_sorted_tags_help<'a>(
|
||||||
arena: &'a Bump,
|
arena: &'a Bump,
|
||||||
mut tags_vec: std::vec::Vec<(TagName, std::vec::Vec<Variable>)>,
|
mut tags_vec: std::vec::Vec<(TagName, std::vec::Vec<Variable>)>,
|
||||||
|
@ -1623,10 +1635,12 @@ pub fn union_sorted_tags_help<'a>(
|
||||||
for var in arguments {
|
for var in arguments {
|
||||||
match Layout::from_var(&mut env, var) {
|
match Layout::from_var(&mut env, var) {
|
||||||
Ok(layout) => {
|
Ok(layout) => {
|
||||||
// Drop any zero-sized arguments like {}
|
has_any_arguments = true;
|
||||||
if !layout.is_dropped_because_empty() {
|
|
||||||
has_any_arguments = true;
|
|
||||||
|
|
||||||
|
// make sure to not unroll recursive types!
|
||||||
|
if opt_rec_var.is_some() && is_recursive_tag_union(&layout) {
|
||||||
|
arg_layouts.push(Layout::RecursivePointer);
|
||||||
|
} else {
|
||||||
arg_layouts.push(layout);
|
arg_layouts.push(layout);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,20 +32,24 @@ struct CtorInfo<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn may_reuse(tag_layout: UnionLayout, tag_id: u8, other: &CtorInfo) -> bool {
|
fn may_reuse(tag_layout: UnionLayout, tag_id: u8, other: &CtorInfo) -> bool {
|
||||||
// if tag_layout != other.layout {
|
if tag_layout != other.layout {
|
||||||
// return false;
|
return false;
|
||||||
// }
|
}
|
||||||
|
|
||||||
// if the tag id is represented as NULL, there is no memory to re-use
|
|
||||||
match tag_layout {
|
match tag_layout {
|
||||||
UnionLayout::NonRecursive(_)
|
UnionLayout::NonRecursive(_)
|
||||||
| UnionLayout::Recursive(_)
|
| UnionLayout::Recursive(_)
|
||||||
| UnionLayout::NonNullableUnwrapped(_) => true,
|
| UnionLayout::NonNullableUnwrapped(_) => true,
|
||||||
UnionLayout::NullableWrapped { nullable_id, .. } => tag_id as i64 != nullable_id,
|
UnionLayout::NullableWrapped { nullable_id, .. } => {
|
||||||
UnionLayout::NullableUnwrapped {
|
// if the source tag id is represented as NULL, there is no memory to re-use
|
||||||
nullable_id,
|
// if the current tag id is represented as NULL, then we don't need to re-use the
|
||||||
other_fields,
|
// memory here and can use it somewhere else
|
||||||
} => (tag_id != 0) != nullable_id,
|
other.id as i64 != nullable_id && tag_id as i64 != nullable_id
|
||||||
|
}
|
||||||
|
UnionLayout::NullableUnwrapped { nullable_id, .. } => {
|
||||||
|
// idem
|
||||||
|
(other.id != 0) != nullable_id && (tag_id != 0) != nullable_id
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue