mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-03 16:44:33 +00:00
Extract some common wrapper logic
This commit is contained in:
parent
efa31ae747
commit
e9966e6551
1 changed files with 18 additions and 14 deletions
|
@ -534,7 +534,10 @@ pub enum RocTagUnion {
|
||||||
/// A recursive tag union with just one constructor
|
/// A recursive tag union with just one constructor
|
||||||
/// Optimization: No need to store a tag ID (the payload is "unwrapped")
|
/// Optimization: No need to store a tag ID (the payload is "unwrapped")
|
||||||
/// e.g. `RoseTree a : [Tree a (List (RoseTree a))]`
|
/// e.g. `RoseTree a : [Tree a (List (RoseTree a))]`
|
||||||
NonNullableUnwrapped { name: String, content: TypeId },
|
NonNullableUnwrapped {
|
||||||
|
name: String,
|
||||||
|
content: TypeId,
|
||||||
|
},
|
||||||
|
|
||||||
/// A recursive tag union that has an empty variant
|
/// A recursive tag union that has an empty variant
|
||||||
/// Optimization: Represent the empty variant as null pointer => no memory usage & fast comparison
|
/// Optimization: Represent the empty variant as null pointer => no memory usage & fast comparison
|
||||||
|
@ -1016,7 +1019,7 @@ fn add_tag_union<'a>(
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let typ = match layout {
|
let tag_union_type = match layout {
|
||||||
Layout::Union(union_layout) => {
|
Layout::Union(union_layout) => {
|
||||||
use UnionLayout::*;
|
use UnionLayout::*;
|
||||||
|
|
||||||
|
@ -1030,12 +1033,12 @@ fn add_tag_union<'a>(
|
||||||
.max(1);
|
.max(1);
|
||||||
let discriminant_offset = union_layout.tag_id_offset(env.target).unwrap();
|
let discriminant_offset = union_layout.tag_id_offset(env.target).unwrap();
|
||||||
|
|
||||||
RocType::TagUnion(RocTagUnion::NonRecursive {
|
RocTagUnion::NonRecursive {
|
||||||
name: name.clone(),
|
name: name.clone(),
|
||||||
tags,
|
tags,
|
||||||
discriminant_size,
|
discriminant_size,
|
||||||
discriminant_offset,
|
discriminant_offset,
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
// A recursive tag union (general case)
|
// A recursive tag union (general case)
|
||||||
// e.g. `Expr : [Sym Str, Add Expr Expr]`
|
// e.g. `Expr : [Sym Str, Add Expr Expr]`
|
||||||
|
@ -1044,12 +1047,12 @@ fn add_tag_union<'a>(
|
||||||
Discriminant::from_number_of_tags(tags.len()).stack_size();
|
Discriminant::from_number_of_tags(tags.len()).stack_size();
|
||||||
let discriminant_offset = union_layout.tag_id_offset(env.target).unwrap();
|
let discriminant_offset = union_layout.tag_id_offset(env.target).unwrap();
|
||||||
|
|
||||||
RocType::TagUnion(RocTagUnion::Recursive {
|
RocTagUnion::Recursive {
|
||||||
name: name.clone(),
|
name: name.clone(),
|
||||||
tags,
|
tags,
|
||||||
discriminant_size,
|
discriminant_size,
|
||||||
discriminant_offset,
|
discriminant_offset,
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
// A recursive tag union with just one constructor
|
// A recursive tag union with just one constructor
|
||||||
// Optimization: No need to store a tag ID (the payload is "unwrapped")
|
// Optimization: No need to store a tag ID (the payload is "unwrapped")
|
||||||
|
@ -1091,41 +1094,42 @@ fn add_tag_union<'a>(
|
||||||
|
|
||||||
let (non_null_tag, non_null_payload) = non_null;
|
let (non_null_tag, non_null_payload) = non_null;
|
||||||
|
|
||||||
RocType::TagUnion(RocTagUnion::NullableUnwrapped {
|
RocTagUnion::NullableUnwrapped {
|
||||||
name: name.clone(),
|
name: name.clone(),
|
||||||
null_tag,
|
null_tag,
|
||||||
non_null_tag,
|
non_null_tag,
|
||||||
non_null_payload: non_null_payload.unwrap(),
|
non_null_payload: non_null_payload.unwrap(),
|
||||||
null_represents_first_tag,
|
null_represents_first_tag,
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Layout::Builtin(Builtin::Int(int_width)) => RocType::TagUnion(RocTagUnion::Enumeration {
|
Layout::Builtin(Builtin::Int(int_width)) => RocTagUnion::Enumeration {
|
||||||
name: name.clone(),
|
name: name.clone(),
|
||||||
tags: tags.into_iter().map(|(tag_name, _)| tag_name).collect(),
|
tags: tags.into_iter().map(|(tag_name, _)| tag_name).collect(),
|
||||||
size: int_width.stack_size(),
|
size: int_width.stack_size(),
|
||||||
}),
|
},
|
||||||
Layout::Builtin(_)
|
Layout::Builtin(_)
|
||||||
| Layout::Struct { .. }
|
| Layout::Struct { .. }
|
||||||
| Layout::Boxed(_)
|
| Layout::Boxed(_)
|
||||||
| Layout::LambdaSet(_)
|
| Layout::LambdaSet(_)
|
||||||
| Layout::RecursivePointer => {
|
| Layout::RecursivePointer => {
|
||||||
// These must be single-tag unions. Generate ordinary nonrecursive
|
// These must be single-tag wrappers. Generate ordinary nonrecursive
|
||||||
// tag unions for them, and let Rust do the unwrapping.
|
// tag unions for them, and let the generator do any unwrapping.
|
||||||
//
|
//
|
||||||
// This should be a very rare use case, and it's not worth overcomplicating
|
// This should be a very rare use case, and it's not worth overcomplicating
|
||||||
// the rest of glue to make it do something different.
|
// the rest of glue to make it do something different.
|
||||||
RocType::TagUnion(RocTagUnion::NonRecursive {
|
RocTagUnion::NonRecursive {
|
||||||
name: name.clone(),
|
name: name.clone(),
|
||||||
tags,
|
tags,
|
||||||
// These actually have no discriminant, since there's only one tag.
|
// These actually have no discriminant, since there's only one tag.
|
||||||
discriminant_size: 1,
|
discriminant_size: 1,
|
||||||
discriminant_offset: 0,
|
discriminant_offset: 0,
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let typ = RocType::TagUnion(tag_union_type);
|
||||||
let type_id = types.add_named(name, typ, layout);
|
let type_id = types.add_named(name, typ, layout);
|
||||||
|
|
||||||
if is_recursive {
|
if is_recursive {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue