Merge branch 'trunk' of https://github.com/rtfeldman/roc into add-dec-types

This commit is contained in:
Jared Ramirez 2021-07-08 16:47:42 -07:00
commit 67eef2c97f
82 changed files with 3791 additions and 2228 deletions

View file

@ -14,11 +14,6 @@ const GENERATE_NULLABLE: bool = true;
/// If a (Num *) gets translated to a Layout, this is the numeric type it defaults to.
const DEFAULT_NUM_BUILTIN: Builtin<'_> = Builtin::Int64;
pub const TAG_SIZE: Builtin<'_> = Builtin::Int64;
impl Layout<'_> {
pub const TAG_SIZE: Layout<'static> = Layout::Builtin(Builtin::Int64);
}
#[derive(Debug, Clone)]
pub enum LayoutProblem {
@ -152,6 +147,54 @@ impl<'a> UnionLayout<'a> {
result
}
}
fn tag_id_builtin_help(union_size: usize) -> Builtin<'a> {
if union_size <= u8::MAX as usize {
Builtin::Int8
} else if union_size <= u16::MAX as usize {
Builtin::Int16
} else {
panic!("tag union is too big")
}
}
pub fn tag_id_builtin(&self) -> Builtin<'a> {
match self {
UnionLayout::NonRecursive(tags) | UnionLayout::Recursive(tags) => {
let union_size = tags.len();
Self::tag_id_builtin_help(union_size)
}
UnionLayout::NullableWrapped { other_tags, .. } => {
Self::tag_id_builtin_help(other_tags.len() + 1)
}
UnionLayout::NonNullableUnwrapped(_) => Builtin::Int1,
UnionLayout::NullableUnwrapped { .. } => Builtin::Int1,
}
}
pub fn tag_id_layout(&self) -> Layout<'a> {
Layout::Builtin(self.tag_id_builtin())
}
pub fn stores_tag_id(&self) -> bool {
match self {
UnionLayout::NonRecursive(_)
| UnionLayout::Recursive(_)
| UnionLayout::NullableWrapped { .. } => true,
UnionLayout::NonNullableUnwrapped(_) | UnionLayout::NullableUnwrapped { .. } => false,
}
}
pub fn is_nullable(&self) -> bool {
match self {
UnionLayout::NonRecursive(_)
| UnionLayout::Recursive(_)
| UnionLayout::NonNullableUnwrapped { .. } => false,
UnionLayout::NullableWrapped { .. } | UnionLayout::NullableUnwrapped { .. } => true,
}
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
@ -565,16 +608,20 @@ impl<'a> Layout<'a> {
use UnionLayout::*;
match variant {
NonRecursive(fields) => fields
.iter()
.map(|tag_layout| {
tag_layout
.iter()
.map(|field| field.stack_size(pointer_size))
.sum()
})
.max()
.unwrap_or_default(),
NonRecursive(fields) => {
fields
.iter()
.map(|tag_layout| {
tag_layout
.iter()
.map(|field| field.stack_size(pointer_size))
.sum::<u32>()
})
.max()
.unwrap_or_default()
// the size of the tag_id
+ pointer_size
}
Recursive(_)
| NullableWrapped { .. }
@ -1195,15 +1242,12 @@ fn layout_from_flat_type<'a>(
env.insert_seen(rec_var);
for (index, (_name, variables)) in tags_vec.into_iter().enumerate() {
if matches!(nullable, Some(i) if i == index as i64) {
// don't add the
// don't add the nullable case
continue;
}
let mut tag_layout = Vec::with_capacity_in(variables.len() + 1, arena);
// store the discriminant
tag_layout.push(Layout::Builtin(TAG_SIZE));
for var in variables {
// TODO does this cause problems with mutually recursive unions?
if rec_var == subs.get_root_key_without_compacting(var) {
@ -1244,7 +1288,7 @@ fn layout_from_flat_type<'a>(
}
} else if tag_layouts.len() == 1 {
// drop the tag id
UnionLayout::NonNullableUnwrapped(&tag_layouts.pop().unwrap()[1..])
UnionLayout::NonNullableUnwrapped(&tag_layouts.pop().unwrap())
} else {
UnionLayout::Recursive(tag_layouts.into_bump_slice())
};
@ -1586,9 +1630,6 @@ pub fn union_sorted_tags_help<'a>(
let mut arg_layouts = Vec::with_capacity_in(arguments.len() + 1, arena);
// add the tag discriminant (size currently always hardcoded to i64)
arg_layouts.push(Layout::Builtin(TAG_SIZE));
for var in arguments {
match Layout::from_var(&mut env, var) {
Ok(layout) => {