Revert "Attempt at making recursive tag unions better"

This reverts commit 51e69e93c7.
This commit is contained in:
Richard Feldman 2022-05-28 11:48:42 -04:00
parent 51e69e93c7
commit 13acea4704
No known key found for this signature in database
GPG Key ID: 7E4127D1E4241798
2 changed files with 11 additions and 78 deletions

View File

@ -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, .. })

View File

@ -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.