mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-28 14:24:45 +00:00
stub out Tag layout
This commit is contained in:
parent
6088a22cb6
commit
5926ac2f01
3 changed files with 23 additions and 16 deletions
|
@ -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,
|
||||||
|
|
|
@ -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");
|
||||||
}
|
}
|
||||||
|
|
|
@ -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),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue