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) => {
|
Layout::Union(layouts) | Layout::RecursiveUnion(layouts) => {
|
||||||
layouts[*tag_id as usize]
|
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,
|
Layout::Struct(layouts) => layouts,
|
||||||
other => env.arena.alloc([other.clone()]),
|
other => env.arena.alloc([other.clone()]),
|
||||||
};
|
};
|
||||||
|
|
|
@ -827,6 +827,7 @@ impl Wrapped {
|
||||||
},
|
},
|
||||||
_ => Some(Wrapped::MultiTagUnion),
|
_ => Some(Wrapped::MultiTagUnion),
|
||||||
},
|
},
|
||||||
|
Layout::NullableUnion { .. } => Some(Wrapped::MultiTagUnion),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1019,7 +1019,21 @@ fn layout_from_flat_type<'a>(
|
||||||
let mut tags_vec: std::vec::Vec<_> = tags.into_iter().collect();
|
let mut tags_vec: std::vec::Vec<_> = tags.into_iter().collect();
|
||||||
tags_vec.sort();
|
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);
|
let mut tag_layout = Vec::with_capacity_in(variables.len() + 1, arena);
|
||||||
|
|
||||||
// store the discriminant
|
// store the discriminant
|
||||||
|
@ -1047,7 +1061,15 @@ fn layout_from_flat_type<'a>(
|
||||||
tag_layouts.push(tag_layout.into_bump_slice());
|
tag_layouts.push(tag_layout.into_bump_slice());
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(Layout::RecursiveUnion(tag_layouts.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 => {
|
EmptyTagUnion => {
|
||||||
panic!("TODO make Layout for empty Tag Union");
|
panic!("TODO make Layout for empty Tag Union");
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue