diff --git a/compiler/gen/src/crane/convert.rs b/compiler/gen/src/crane/convert.rs index 857cbdf8f9..f575052d62 100644 --- a/compiler/gen/src/crane/convert.rs +++ b/compiler/gen/src/crane/convert.rs @@ -10,7 +10,7 @@ pub fn type_from_layout(cfg: TargetFrontendConfig, layout: &Layout<'_>) -> Type use roc_mono::layout::Layout::*; match layout { - Pointer(_) | FunctionPointer(_, _) | Struct(_) | Tag(_) => cfg.pointer_type(), + Pointer(_) | FunctionPointer(_, _) | Struct(_) | Union(_) => cfg.pointer_type(), Builtin(builtin) => match builtin { Int64 => types::I64, Float64 => types::F64, diff --git a/compiler/gen/src/llvm/convert.rs b/compiler/gen/src/llvm/convert.rs index 2c8c16dd6e..c09068a420 100644 --- a/compiler/gen/src/llvm/convert.rs +++ b/compiler/gen/src/llvm/convert.rs @@ -68,7 +68,7 @@ pub fn basic_type_from_layout<'ctx>( .struct_type(field_types.into_bump_slice(), false) .as_basic_type_enum() } - Tag(_fields) => { + Union(_fields) => { panic!("TODO layout_to_basic_type for Tag"); } Pointer(_layout) => { diff --git a/compiler/mono/src/decision_tree.rs b/compiler/mono/src/decision_tree.rs index 1c09630641..71d725a1b3 100644 --- a/compiler/mono/src/decision_tree.rs +++ b/compiler/mono/src/decision_tree.rs @@ -124,7 +124,9 @@ fn flatten_patterns<'a>(branch: Branch<'a>) -> Branch<'a> { fn flatten<'a>(path_pattern: (Path, Pattern<'a>), path_patterns: &mut Vec<(Path, Pattern<'a>)>) { match &path_pattern.1 { - Pattern::AppliedTag { union, .. } => { + Pattern::AppliedTag { + union, arguments, .. + } => { if union.alternatives.len() == 1 { // case map dearg ctorArgs of // [arg] -> diff --git a/compiler/mono/src/expr.rs b/compiler/mono/src/expr.rs index bdb16952bb..91cf15d6cb 100644 --- a/compiler/mono/src/expr.rs +++ b/compiler/mono/src/expr.rs @@ -104,6 +104,7 @@ pub struct Env<'a, 'i> { pub ident_ids: &'i mut IdentIds, pub pointer_size: u32, symbol_counter: usize, + pub jump_counter: &'a mut u64, } impl<'a, 'i> Env<'a, 'i> { @@ -217,6 +218,7 @@ impl<'a> Expr<'a> { ident_ids, pointer_size, symbol_counter: 0, + jump_counter: arena.alloc(0), }; from_can(&mut env, can_expr, procs, None) diff --git a/compiler/mono/src/layout.rs b/compiler/mono/src/layout.rs index 2a7c716e32..ea17bff3fa 100644 --- a/compiler/mono/src/layout.rs +++ b/compiler/mono/src/layout.rs @@ -10,7 +10,7 @@ use roc_types::subs::{Content, FlatType, Subs, Variable}; pub enum Layout<'a> { Builtin(Builtin<'a>), Struct(&'a [(Lowercase, Layout<'a>)]), - Tag(&'a [Layout<'a>]), + Union(&'a MutMap]>), Pointer(&'a Layout<'a>), /// A function. The types of its arguments, then the type of its return value. FunctionPointer(&'a [Layout<'a>], &'a Layout<'a>), @@ -93,12 +93,15 @@ impl<'a> Layout<'a> { sum } - Tag(fields) => { - // the symbol is a 64-bit value, so 8 bytes - let mut sum = 8; + Union(fields) => { + // the tag gets converted to a u8, so 1 byte. + // But for one-tag unions, we don't store the tag, so 0 bytes + let mut sum = (fields.len() > 1) as u32; - for field_layout in *fields { - sum += field_layout.stack_size(pointer_size); + for (_, tag_layout) in *fields { + for field_layout in *tag_layout { + sum += field_layout.stack_size(pointer_size); + } } sum @@ -344,8 +347,18 @@ fn layout_from_flat_type<'a>( Ok(Layout::Builtin(Builtin::Byte(tag_to_u8))) } } else { - // panic!("TODO handle a tag union with mutliple tags: {:?}", tags); - Ok(Layout::Tag(&[])) + let mut layouts = MutMap::default(); + for (tag_name, arguments) in tags { + let mut arg_layouts = Vec::with_capacity_in(arguments.len(), arena); + + for arg in arguments { + arg_layouts.push(Layout::from_var(arena, arg, subs, pointer_size)?); + } + + layouts.insert(tag_name, arg_layouts.into_bump_slice()); + } + + Ok(Layout::Union(arena.alloc(layouts))) } } }