mirror of
https://github.com/roc-lang/roc.git
synced 2024-11-11 05:34:11 +03:00
Revert "Attempt at making recursive tag unions better"
This reverts commit 51e69e93c7
.
This commit is contained in:
parent
51e69e93c7
commit
13acea4704
@ -125,9 +125,6 @@ fn add_type(architecture: Architecture, id: TypeId, types: &Types, impls: &mut I
|
||||
RocType::Struct { name, fields } => {
|
||||
add_struct(name, architecture, fields, id, types, impls)
|
||||
}
|
||||
RocType::TagUnionPayload { name, fields } => {
|
||||
add_payload(name, architecture, fields, id, types, impls)
|
||||
}
|
||||
RocType::TagUnion(tag_union) => {
|
||||
match tag_union {
|
||||
RocTagUnion::Enumeration { tags, name } => {
|
||||
@ -594,7 +591,7 @@ pub struct {name} {{
|
||||
borrowed_ret = format!("&{owned_ret}");
|
||||
}
|
||||
RocType::Struct { fields, .. } => {
|
||||
let mut sorted_fields = fields.iter().collect::<Vec<&Field<_>>>();
|
||||
let mut sorted_fields = fields.iter().collect::<Vec<&Field>>();
|
||||
|
||||
sorted_fields.sort_by(|field1, field2| {
|
||||
// Convert from e.g. "f12" to 12u64
|
||||
@ -1202,7 +1199,7 @@ fn add_enumeration<I: ExactSizeIterator<Item = S>, S: AsRef<str> + Display>(
|
||||
fn add_struct(
|
||||
name: &str,
|
||||
architecture: Architecture,
|
||||
fields: &[Field<String>],
|
||||
fields: &[Field],
|
||||
struct_id: TypeId,
|
||||
types: &Types,
|
||||
impls: &mut Impls,
|
||||
@ -1238,49 +1235,6 @@ fn add_struct(
|
||||
}
|
||||
}
|
||||
|
||||
fn add_payload(
|
||||
name: &str,
|
||||
architecture: Architecture,
|
||||
fields: &[Field<u64>],
|
||||
payload_id: TypeId,
|
||||
types: &Types,
|
||||
impls: &mut Impls,
|
||||
) {
|
||||
match fields.len() {
|
||||
0 => {
|
||||
// An empty payload is zero-sized and won't end up being passed to/from the host.
|
||||
}
|
||||
1 => {
|
||||
// Unwrap single-field payloads
|
||||
add_type(
|
||||
architecture,
|
||||
fields.first().unwrap().type_id(),
|
||||
types,
|
||||
impls,
|
||||
)
|
||||
}
|
||||
_ => {
|
||||
// these never get a Debug impl, because they should always be debug-printed
|
||||
// using their tag union's custom Debug implementation.
|
||||
let derive = derive_str(types.get(payload_id), types, false);
|
||||
// payload structs are private
|
||||
let mut buf = format!("{derive}\n#[repr(C)]\nstruct {name} {{\n");
|
||||
|
||||
for field in fields {
|
||||
let label = field.label();
|
||||
let type_str = type_name(field.type_id(), types);
|
||||
|
||||
// The labels are numeric, so print them as f0, f1, f2, etc.
|
||||
buf.push_str(&format!("{INDENT}pub f{label}: {type_str},\n",));
|
||||
}
|
||||
|
||||
buf.push('}');
|
||||
|
||||
add_decl(impls, None, architecture, buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn type_name(id: TypeId, types: &Types) -> String {
|
||||
match types.get(id) {
|
||||
RocType::U8 => "u8".to_string(),
|
||||
@ -1308,7 +1262,6 @@ fn type_name(id: TypeId, types: &Types) -> String {
|
||||
RocType::RocList(elem_id) => format!("roc_std::RocList<{}>", type_name(*elem_id, types)),
|
||||
RocType::RocBox(elem_id) => format!("roc_std::RocBox<{}>", type_name(*elem_id, types)),
|
||||
RocType::Struct { name, .. }
|
||||
| RocType::TagUnionPayload { name, .. }
|
||||
| RocType::TransparentWrapper { name, .. }
|
||||
| RocType::TagUnion(RocTagUnion::NonRecursive { name, .. })
|
||||
| RocType::TagUnion(RocTagUnion::Recursive { name, .. })
|
||||
|
@ -4,9 +4,7 @@ use roc_collections::VecMap;
|
||||
use roc_mono::layout::UnionLayout;
|
||||
use roc_std::RocDec;
|
||||
use roc_target::TargetInfo;
|
||||
use std::cmp::Ordering;
|
||||
use std::convert::TryInto;
|
||||
use std::fmt::Display;
|
||||
|
||||
#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
||||
pub struct TypeId(usize);
|
||||
@ -140,7 +138,7 @@ pub enum RocType {
|
||||
TagUnion(RocTagUnion),
|
||||
Struct {
|
||||
name: String,
|
||||
fields: Vec<Field<String>>,
|
||||
fields: Vec<Field>,
|
||||
},
|
||||
/// Either a single-tag union or a single-field record
|
||||
TransparentWrapper {
|
||||
@ -150,15 +148,15 @@ pub enum RocType {
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub enum Field<T: Ord + Display> {
|
||||
NonRecursive(T, TypeId),
|
||||
pub enum Field {
|
||||
NonRecursive(String, TypeId),
|
||||
/// A recursive field, e.g. in StrConsList : [Nil, Cons Str StrConsList],
|
||||
/// this would be the field of Cons containing the (recursive) StrConsList type,
|
||||
/// and the TypeId is the TypeId of StrConsList itself.
|
||||
Recursive(T, TypeId),
|
||||
Recursive(String, TypeId),
|
||||
}
|
||||
|
||||
impl<T: Ord + Display> Field<T> {
|
||||
impl Field {
|
||||
pub fn type_id(&self) -> TypeId {
|
||||
match self {
|
||||
Field::NonRecursive(_, type_id) => *type_id,
|
||||
@ -166,7 +164,7 @@ impl<T: Ord + Display> Field<T> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn label(&self) -> &T {
|
||||
pub fn label(&self) -> &str {
|
||||
match self {
|
||||
Field::NonRecursive(label, _) => label,
|
||||
Field::Recursive(label, _) => label,
|
||||
@ -174,18 +172,6 @@ impl<T: Ord + Display> Field<T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Ord + Display> Ord for Field<T> {
|
||||
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
|
||||
self.label().cmp(other.label())
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Ord + Display> PartialOrd for Field<T> {
|
||||
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
||||
self.label().partial_cmp(other.label())
|
||||
}
|
||||
}
|
||||
|
||||
impl RocType {
|
||||
/// Useful when determining whether to derive Copy in a Rust type.
|
||||
pub fn has_pointer(&self, types: &Types) -> bool {
|
||||
@ -539,12 +525,6 @@ fn align_for_tag_count(num_tags: usize, target_info: TargetInfo) -> usize {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct TagUnionPayload {
|
||||
name: String,
|
||||
fields: Vec<Field<u64>>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub enum RocTagUnion {
|
||||
Enumeration {
|
||||
@ -555,13 +535,13 @@ pub enum RocTagUnion {
|
||||
/// e.g. `Result a e : [Ok a, Err e]`
|
||||
NonRecursive {
|
||||
name: String,
|
||||
tags: Vec<(String, Option<TagUnionPayload>)>,
|
||||
tags: Vec<(String, Option<TypeId>)>,
|
||||
},
|
||||
/// A recursive tag union (general case)
|
||||
/// e.g. `Expr : [Sym Str, Add Expr Expr]`
|
||||
Recursive {
|
||||
name: String,
|
||||
tags: Vec<(String, Option<TagUnionPayload>)>,
|
||||
tags: Vec<(String, Option<TypeId>)>,
|
||||
},
|
||||
/// A recursive tag union with just one constructor
|
||||
/// Optimization: No need to store a tag ID (the payload is "unwrapped")
|
||||
@ -579,7 +559,7 @@ pub enum RocTagUnion {
|
||||
NullableWrapped {
|
||||
name: String,
|
||||
null_tag: String,
|
||||
non_null_tags: Vec<(u16, String, Option<TagUnionPayload>)>,
|
||||
non_null_tags: Vec<(u16, String, Option<TypeId>)>,
|
||||
},
|
||||
|
||||
/// A recursive tag union with only two variants, where one is empty.
|
||||
|
Loading…
Reference in New Issue
Block a user