stub out Tag layout

This commit is contained in:
Folkert 2020-03-15 00:56:35 +01:00
parent 6088a22cb6
commit 5926ac2f01
3 changed files with 23 additions and 16 deletions

View file

@ -10,7 +10,7 @@ pub fn type_from_layout(cfg: TargetFrontendConfig, layout: &Layout<'_>) -> Type
use roc_mono::layout::Layout::*; use roc_mono::layout::Layout::*;
match layout { match layout {
Pointer(_) | FunctionPointer(_, _) | Struct(_) => cfg.pointer_type(), Pointer(_) | FunctionPointer(_, _) | Struct(_) | Tag(_) => cfg.pointer_type(),
Builtin(builtin) => match builtin { Builtin(builtin) => match builtin {
Int64 => types::I64, Int64 => types::I64,
Float64 => types::F64, Float64 => types::F64,

View file

@ -56,6 +56,9 @@ pub fn basic_type_from_layout<'ctx>(
Struct(_fields) => { Struct(_fields) => {
panic!("TODO layout_to_basic_type for Struct"); panic!("TODO layout_to_basic_type for Struct");
} }
Tag(_fields) => {
panic!("TODO layout_to_basic_type for Tag");
}
Pointer(_layout) => { Pointer(_layout) => {
panic!("TODO layout_to_basic_type for Pointer"); panic!("TODO layout_to_basic_type for Pointer");
} }

View file

@ -10,6 +10,7 @@ use roc_types::subs::{Content, FlatType, Subs, Variable};
pub enum Layout<'a> { pub enum Layout<'a> {
Builtin(Builtin<'a>), Builtin(Builtin<'a>),
Struct(&'a [(Lowercase, Layout<'a>)]), Struct(&'a [(Lowercase, Layout<'a>)]),
Tag(&'a [Layout<'a>]),
Pointer(&'a Layout<'a>), Pointer(&'a Layout<'a>),
/// A function. The types of its arguments, then the type of its return value. /// A function. The types of its arguments, then the type of its return value.
FunctionPointer(&'a [Layout<'a>], &'a Layout<'a>), FunctionPointer(&'a [Layout<'a>], &'a Layout<'a>),
@ -92,6 +93,16 @@ impl<'a> Layout<'a> {
sum sum
} }
Tag(fields) => {
// the symbol is a 64-bit value, so 8 bytes
let mut sum = 8;
for field_layout in *fields {
sum += field_layout.stack_size(pointer_size);
}
sum
}
Pointer(_) | FunctionPointer(_, _) => pointer_size, Pointer(_) | FunctionPointer(_, _) => pointer_size,
} }
} }
@ -264,7 +275,9 @@ fn layout_from_flat_type<'a>(
0 => { 0 => {
panic!("TODO gracefully handle trying to instantiate Never"); panic!("TODO gracefully handle trying to instantiate Never");
} }
1 => { // We can only unwrap a wrapper if it never becomes part of a bigger union
// therefore, the ext_var must be the literal empty tag union
1 if ext_var == Variable::EMPTY_TAG_UNION => {
// This is a wrapper. Unwrap it! // This is a wrapper. Unwrap it!
let (tag, args) = tags.into_iter().next().unwrap(); let (tag, args) = tags.into_iter().next().unwrap();
@ -294,6 +307,7 @@ fn layout_from_flat_type<'a>(
// But when one-tag tag unions are optimized away, we can also use an enum for // But when one-tag tag unions are optimized away, we can also use an enum for
// //
// [ Foo [ Unit ], Bar [ Unit ] ] // [ Foo [ Unit ], Bar [ Unit ] ]
let arguments_have_size_0 = || { let arguments_have_size_0 = || {
tags.iter().all(|(_, args)| { tags.iter().all(|(_, args)| {
args.iter().all(|var| { args.iter().all(|var| {
@ -327,7 +341,8 @@ fn layout_from_flat_type<'a>(
Ok(Layout::Builtin(Builtin::Byte(tag_to_u8))) Ok(Layout::Builtin(Builtin::Byte(tag_to_u8)))
} }
} else { } else {
panic!("TODO handle a tag union with mutliple tags: {:?}", tags); // panic!("TODO handle a tag union with mutliple tags: {:?}", tags);
Ok(Layout::Tag(&[]))
} }
} }
} }
@ -350,12 +365,7 @@ fn ext_var_is_empty_tag_union(subs: &Subs, ext_var: Variable) -> bool {
// the ext_var is empty // the ext_var is empty
let mut ext_fields = std::vec::Vec::new(); let mut ext_fields = std::vec::Vec::new();
match roc_types::pretty_print::chase_ext_tag_union(subs, ext_var, &mut ext_fields) { match roc_types::pretty_print::chase_ext_tag_union(subs, ext_var, &mut ext_fields) {
Ok(()) | Err((_, Content::FlexVar(_))) => { Ok(()) | Err((_, Content::FlexVar(_))) => ext_fields.is_empty(),
if !ext_fields.is_empty() {
println!("ext_tags: {:?}", ext_fields);
}
ext_fields.is_empty()
}
Err(content) => panic!("invalid content in ext_var: {:?}", content), Err(content) => panic!("invalid content in ext_var: {:?}", content),
} }
} }
@ -364,13 +374,7 @@ fn ext_var_is_empty_record(subs: &Subs, ext_var: Variable) -> bool {
// the ext_var is empty // the ext_var is empty
let mut ext_fields = MutMap::default(); let mut ext_fields = MutMap::default();
match roc_types::pretty_print::chase_ext_record(subs, ext_var, &mut ext_fields) { match roc_types::pretty_print::chase_ext_record(subs, ext_var, &mut ext_fields) {
Ok(()) | Err((_, Content::FlexVar(_))) => { Ok(()) | Err((_, Content::FlexVar(_))) => ext_fields.is_empty(),
if !ext_fields.is_empty() {
println!("ext_fields: {:?}", ext_fields);
}
ext_fields.is_empty()
}
Err((_, content)) => panic!("invalid content in ext_var: {:?}", content), Err((_, content)) => panic!("invalid content in ext_var: {:?}", content),
} }
} }