mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-26 13:29:12 +00:00
Begin support for looping-back recursive pointers to their source layouts
This commit is contained in:
parent
a30a4e36ed
commit
8750127111
17 changed files with 57 additions and 47 deletions
|
@ -45,7 +45,7 @@ pub fn eq_generic<'a>(
|
|||
eq_boxed(root, ident_ids, ctx, layout_interner, inner_layout)
|
||||
}
|
||||
Layout::LambdaSet(_) => unreachable!("`==` is not defined on functions"),
|
||||
Layout::RecursivePointer => {
|
||||
Layout::RecursivePointer(_) => {
|
||||
unreachable!(
|
||||
"Can't perform `==` on RecursivePointer. Should have been replaced by a tag union."
|
||||
)
|
||||
|
@ -451,7 +451,7 @@ fn eq_tag_fields<'a>(
|
|||
// (If there are more than one, the others will use non-tail recursion)
|
||||
let rec_ptr_index = field_layouts
|
||||
.iter()
|
||||
.position(|field| matches!(layout_interner.get(*field), Layout::RecursivePointer));
|
||||
.position(|field| matches!(layout_interner.get(*field), Layout::RecursivePointer(_)));
|
||||
|
||||
let (tailrec_index, innermost_stmt) = match rec_ptr_index {
|
||||
None => {
|
||||
|
|
|
@ -255,7 +255,10 @@ impl<'a> CodeGenHelp<'a> {
|
|||
// debug_assert!(self.debug_recursion_depth < 100);
|
||||
self.debug_recursion_depth += 1;
|
||||
|
||||
let layout = if matches!(layout_interner.get(called_layout), Layout::RecursivePointer) {
|
||||
let layout = if matches!(
|
||||
layout_interner.get(called_layout),
|
||||
Layout::RecursivePointer(_)
|
||||
) {
|
||||
let union_layout = ctx.recursive_union.unwrap();
|
||||
layout_interner.insert(Layout::Union(union_layout))
|
||||
} else {
|
||||
|
@ -494,7 +497,7 @@ impl<'a> CodeGenHelp<'a> {
|
|||
}
|
||||
|
||||
// This line is the whole point of the function
|
||||
Layout::RecursivePointer => Layout::Union(ctx.recursive_union.unwrap()),
|
||||
Layout::RecursivePointer(_) => Layout::Union(ctx.recursive_union.unwrap()),
|
||||
};
|
||||
layout_interner.insert(layout)
|
||||
}
|
||||
|
@ -535,7 +538,7 @@ impl<'a> CodeGenHelp<'a> {
|
|||
for fields in tags.iter() {
|
||||
let found_index = fields
|
||||
.iter()
|
||||
.position(|f| matches!(layout_interner.get(*f), Layout::RecursivePointer));
|
||||
.position(|f| matches!(layout_interner.get(*f), Layout::RecursivePointer(_)));
|
||||
tailrec_indices.push(found_index);
|
||||
can_use_tailrec |= found_index.is_some();
|
||||
}
|
||||
|
@ -586,7 +589,7 @@ fn layout_needs_helper_proc<'a>(
|
|||
Layout::Union(UnionLayout::NonRecursive(tags)) => !tags.is_empty(),
|
||||
Layout::Union(_) => true,
|
||||
Layout::LambdaSet(_) => true,
|
||||
Layout::RecursivePointer => false,
|
||||
Layout::RecursivePointer(_) => false,
|
||||
Layout::Boxed(_) => true,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -176,7 +176,7 @@ pub fn refcount_generic<'a>(
|
|||
structure,
|
||||
)
|
||||
}
|
||||
Layout::RecursivePointer => unreachable!(
|
||||
Layout::RecursivePointer(_) => unreachable!(
|
||||
"We should never call a refcounting helper on a RecursivePointer layout directly"
|
||||
),
|
||||
Layout::Boxed(inner_layout) => refcount_boxed(
|
||||
|
@ -450,7 +450,7 @@ where
|
|||
.all(|l| is_rc_implemented_yet(interner, *l)),
|
||||
},
|
||||
Layout::LambdaSet(lambda_set) => is_rc_implemented_yet(interner, lambda_set.representation),
|
||||
Layout::RecursivePointer => true,
|
||||
Layout::RecursivePointer(_) => true,
|
||||
Layout::Boxed(_) => true,
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue