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
|
@ -1528,7 +1528,7 @@ fn build_tag_field_value<'a, 'ctx, 'env>(
|
|||
value: BasicValueEnum<'ctx>,
|
||||
tag_field_layout: InLayout<'a>,
|
||||
) -> BasicValueEnum<'ctx> {
|
||||
if let Layout::RecursivePointer = layout_interner.get(tag_field_layout) {
|
||||
if let Layout::RecursivePointer(_) = layout_interner.get(tag_field_layout) {
|
||||
debug_assert!(value.is_pointer_value());
|
||||
|
||||
// we store recursive pointers as `i64*`
|
||||
|
@ -2020,7 +2020,7 @@ fn lookup_at_index_ptr<'a, 'ctx, 'env>(
|
|||
"load_at_index_ptr_old",
|
||||
);
|
||||
|
||||
if let Some(Layout::RecursivePointer) = field_layouts
|
||||
if let Some(Layout::RecursivePointer(_)) = field_layouts
|
||||
.get(index as usize)
|
||||
.map(|l| layout_interner.get(*l))
|
||||
{
|
||||
|
@ -2080,7 +2080,7 @@ fn lookup_at_index_ptr2<'a, 'ctx, 'env>(
|
|||
"load_at_index_ptr",
|
||||
);
|
||||
|
||||
if let Some(Layout::RecursivePointer) = field_layouts
|
||||
if let Some(Layout::RecursivePointer(_)) = field_layouts
|
||||
.get(index as usize)
|
||||
.map(|l| layout_interner.get(*l))
|
||||
{
|
||||
|
@ -2481,7 +2481,10 @@ pub fn build_exp_stmt<'a, 'ctx, 'env>(
|
|||
let mut stack = Vec::with_capacity_in(queue.len(), env.arena);
|
||||
|
||||
for (symbol, expr, layout) in queue {
|
||||
debug_assert!(layout_interner.get(*layout) != Layout::RecursivePointer);
|
||||
debug_assert!(!matches!(
|
||||
layout_interner.get(*layout),
|
||||
Layout::RecursivePointer(_)
|
||||
));
|
||||
|
||||
let val = build_exp_expr(
|
||||
env,
|
||||
|
@ -6107,7 +6110,7 @@ pub(crate) enum WhenRecursive<'a> {
|
|||
impl<'a> WhenRecursive<'a> {
|
||||
pub fn unwrap_recursive_pointer(&self, layout: Layout<'a>) -> Layout<'a> {
|
||||
match layout {
|
||||
Layout::RecursivePointer => match self {
|
||||
Layout::RecursivePointer(_) => match self {
|
||||
WhenRecursive::Loop(lay) => Layout::Union(*lay),
|
||||
WhenRecursive::Unreachable => {
|
||||
internal_error!("cannot compare recursive pointers outside of a structure")
|
||||
|
|
|
@ -208,7 +208,7 @@ fn build_eq<'a, 'ctx, 'env>(
|
|||
rhs_val,
|
||||
),
|
||||
|
||||
Layout::RecursivePointer => match when_recursive {
|
||||
Layout::RecursivePointer(_) => match when_recursive {
|
||||
WhenRecursive::Unreachable => {
|
||||
unreachable!("recursion pointers should never be compared directly")
|
||||
}
|
||||
|
@ -417,7 +417,7 @@ fn build_neq<'a, 'ctx, 'env>(
|
|||
result.into()
|
||||
}
|
||||
|
||||
Layout::RecursivePointer => {
|
||||
Layout::RecursivePointer(_) => {
|
||||
unreachable!("recursion pointers should never be compared directly")
|
||||
}
|
||||
Layout::LambdaSet(_) => unreachable!("cannot compare closure"),
|
||||
|
@ -761,7 +761,7 @@ fn build_struct_eq_help<'a, 'ctx, 'env>(
|
|||
.build_extract_value(struct2, index as u32, "eq_field")
|
||||
.unwrap();
|
||||
|
||||
let are_equal = if let Layout::RecursivePointer = layout_interner.get(*field_layout) {
|
||||
let are_equal = if let Layout::RecursivePointer(_) = layout_interner.get(*field_layout) {
|
||||
match &when_recursive {
|
||||
WhenRecursive::Unreachable => {
|
||||
unreachable!("The current layout should not be recursive, but is")
|
||||
|
|
|
@ -47,7 +47,7 @@ pub fn basic_type_from_layout<'a, 'ctx, 'env>(
|
|||
inner_type.ptr_type(AddressSpace::Generic).into()
|
||||
}
|
||||
Union(union_layout) => basic_type_from_union_layout(env, layout_interner, &union_layout),
|
||||
RecursivePointer => env
|
||||
RecursivePointer(_) => env
|
||||
.context
|
||||
.i64_type()
|
||||
.ptr_type(AddressSpace::Generic)
|
||||
|
|
|
@ -380,7 +380,7 @@ fn build_clone<'a, 'ctx, 'env>(
|
|||
)
|
||||
}
|
||||
|
||||
Layout::RecursivePointer => match when_recursive {
|
||||
Layout::RecursivePointer(_) => match when_recursive {
|
||||
WhenRecursive::Unreachable => {
|
||||
unreachable!("recursion pointers should never be compared directly")
|
||||
}
|
||||
|
|
|
@ -511,7 +511,7 @@ fn modify_refcount_layout_help<'a, 'ctx, 'env>(
|
|||
};
|
||||
|
||||
match layout_interner.get(layout) {
|
||||
Layout::RecursivePointer => match when_recursive {
|
||||
Layout::RecursivePointer(_) => match when_recursive {
|
||||
WhenRecursive::Unreachable => {
|
||||
unreachable!("recursion pointers should never be hashed directly")
|
||||
}
|
||||
|
@ -640,7 +640,7 @@ fn modify_refcount_layout_build_function<'a, 'ctx, 'env>(
|
|||
Some(function)
|
||||
}
|
||||
|
||||
Layout::RecursivePointer => match when_recursive {
|
||||
Layout::RecursivePointer(_) => match when_recursive {
|
||||
WhenRecursive::Unreachable => {
|
||||
unreachable!("recursion pointers cannot be in/decremented directly")
|
||||
}
|
||||
|
@ -1326,7 +1326,7 @@ fn build_rec_union_recursive_decrement<'a, 'ctx, 'env>(
|
|||
let mut deferred_nonrec = Vec::new_in(env.arena);
|
||||
|
||||
for (i, field_layout) in field_layouts.iter().enumerate() {
|
||||
if let Layout::RecursivePointer = layout_interner.get(*field_layout) {
|
||||
if let Layout::RecursivePointer(_) = layout_interner.get(*field_layout) {
|
||||
// this field has type `*i64`, but is really a pointer to the data we want
|
||||
let elem_pointer = env
|
||||
.builder
|
||||
|
@ -1810,7 +1810,7 @@ fn modify_refcount_nonrecursive_help<'a, 'ctx, 'env>(
|
|||
);
|
||||
|
||||
for (i, field_layout) in field_layouts.iter().enumerate() {
|
||||
if let Layout::RecursivePointer = layout_interner.get(*field_layout) {
|
||||
if let Layout::RecursivePointer(_) = layout_interner.get(*field_layout) {
|
||||
let recursive_union_layout = match when_recursive {
|
||||
WhenRecursive::Unreachable => {
|
||||
panic!("non-recursive tag unions cannot contain naked recursion pointers!");
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue