mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-27 13:59:08 +00:00
create NullableUnion in some cases
This commit is contained in:
parent
b47ccb20fd
commit
51cad15399
3 changed files with 41 additions and 2 deletions
|
@ -1007,6 +1007,22 @@ fn path_to_expr_help<'a>(
|
|||
Layout::Union(layouts) | Layout::RecursiveUnion(layouts) => {
|
||||
layouts[*tag_id as usize]
|
||||
}
|
||||
Layout::NullableUnion {
|
||||
nullable_id,
|
||||
nullable_layout,
|
||||
foo: layouts,
|
||||
..
|
||||
} => {
|
||||
use std::cmp::Ordering;
|
||||
match (*tag_id as usize).cmp(&(*nullable_id as usize)) {
|
||||
Ordering::Equal => {
|
||||
&*env.arena.alloc([Layout::Builtin(nullable_layout.clone())])
|
||||
}
|
||||
Ordering::Less => layouts[*tag_id as usize],
|
||||
Ordering::Greater => layouts[*tag_id as usize - 1],
|
||||
}
|
||||
}
|
||||
|
||||
Layout::Struct(layouts) => layouts,
|
||||
other => env.arena.alloc([other.clone()]),
|
||||
};
|
||||
|
|
|
@ -827,6 +827,7 @@ impl Wrapped {
|
|||
},
|
||||
_ => Some(Wrapped::MultiTagUnion),
|
||||
},
|
||||
Layout::NullableUnion { .. } => Some(Wrapped::MultiTagUnion),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1019,7 +1019,21 @@ fn layout_from_flat_type<'a>(
|
|||
let mut tags_vec: std::vec::Vec<_> = tags.into_iter().collect();
|
||||
tags_vec.sort();
|
||||
|
||||
for (_name, variables) in tags_vec {
|
||||
let mut nullable = None;
|
||||
|
||||
for (index, (_name, variables)) in tags_vec.iter().enumerate() {
|
||||
if variables.is_empty() {
|
||||
nullable = Some((index as i64, TAG_SIZE));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (index, (_name, variables)) in tags_vec.into_iter().enumerate() {
|
||||
if matches!(nullable, Some((i, _)) if i == index as i64) {
|
||||
// don't add the
|
||||
continue;
|
||||
}
|
||||
|
||||
let mut tag_layout = Vec::with_capacity_in(variables.len() + 1, arena);
|
||||
|
||||
// store the discriminant
|
||||
|
@ -1047,8 +1061,16 @@ fn layout_from_flat_type<'a>(
|
|||
tag_layouts.push(tag_layout.into_bump_slice());
|
||||
}
|
||||
|
||||
if let Some((tag_id, tag_id_layout)) = nullable {
|
||||
Ok(Layout::NullableUnion {
|
||||
nullable_id: tag_id,
|
||||
nullable_layout: tag_id_layout,
|
||||
foo: tag_layouts.into_bump_slice(),
|
||||
})
|
||||
} else {
|
||||
Ok(Layout::RecursiveUnion(tag_layouts.into_bump_slice()))
|
||||
}
|
||||
}
|
||||
EmptyTagUnion => {
|
||||
panic!("TODO make Layout for empty Tag Union");
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue