Implement derivation keys for tuple encoders

This commit is contained in:
Ayaz Hafiz 2023-03-22 11:19:47 -05:00
parent a361c4cfc1
commit e5fcb05a2d
No known key found for this signature in database
GPG key ID: 0E2A37416A25EF58
3 changed files with 20 additions and 3 deletions

View file

@ -30,6 +30,7 @@ pub(crate) fn derive_to_encoder(
FlatEncodableKey::List() => to_encoder_list(env, def_symbol), FlatEncodableKey::List() => to_encoder_list(env, def_symbol),
FlatEncodableKey::Set() => todo!(), FlatEncodableKey::Set() => todo!(),
FlatEncodableKey::Dict() => todo!(), FlatEncodableKey::Dict() => todo!(),
FlatEncodableKey::Tuple(_arity) => todo!(),
FlatEncodableKey::Record(fields) => { FlatEncodableKey::Record(fields) => {
// Generalized record var so we can reuse this impl between many records: // Generalized record var so we can reuse this impl between many records:
// if fields = { a, b }, this is { a: t1, b: t2 } for fresh t1, t2. // if fields = { a, b }, this is { a: t1, b: t2 } for fresh t1, t2.

View file

@ -5,7 +5,7 @@ use roc_module::{
use roc_types::subs::{Content, FlatType, GetSubsSlice, Subs, Variable}; use roc_types::subs::{Content, FlatType, GetSubsSlice, Subs, Variable};
use crate::{ use crate::{
util::{check_derivable_ext_var, debug_name_record, debug_name_tag}, util::{check_derivable_ext_var, debug_name_record, debug_name_tag, debug_name_tuple},
DeriveError, DeriveError,
}; };
@ -22,6 +22,7 @@ pub enum FlatEncodableKey {
Dict(/* takes two variables */), Dict(/* takes two variables */),
// Unfortunate that we must allocate here, c'est la vie // Unfortunate that we must allocate here, c'est la vie
Record(Vec<Lowercase>), Record(Vec<Lowercase>),
Tuple(u32),
TagUnion(Vec<(TagName, u16)>), TagUnion(Vec<(TagName, u16)>),
} }
@ -32,6 +33,7 @@ impl FlatEncodableKey {
FlatEncodableKey::Set() => "set".to_string(), FlatEncodableKey::Set() => "set".to_string(),
FlatEncodableKey::Dict() => "dict".to_string(), FlatEncodableKey::Dict() => "dict".to_string(),
FlatEncodableKey::Record(fields) => debug_name_record(fields), FlatEncodableKey::Record(fields) => debug_name_record(fields),
FlatEncodableKey::Tuple(arity) => debug_name_tuple(*arity),
FlatEncodableKey::TagUnion(tags) => debug_name_tag(tags), FlatEncodableKey::TagUnion(tags) => debug_name_tag(tags),
} }
} }
@ -66,8 +68,14 @@ impl FlatEncodable {
Ok(Key(FlatEncodableKey::Record(field_names))) Ok(Key(FlatEncodableKey::Record(field_names)))
} }
FlatType::Tuple(_elems, _ext) => { FlatType::Tuple(elems, ext) => {
todo!() let (elems_iter, ext) = elems.sorted_iterator_and_ext(subs, ext);
check_derivable_ext_var(subs, ext, |ext| {
matches!(ext, Content::Structure(FlatType::EmptyTuple))
})?;
Ok(Key(FlatEncodableKey::Tuple(elems_iter.count() as _)))
} }
FlatType::TagUnion(tags, ext) | FlatType::RecursiveTagUnion(_, tags, ext) => { FlatType::TagUnion(tags, ext) | FlatType::RecursiveTagUnion(_, tags, ext) => {
// The recursion var doesn't matter, because the derived implementation will only // The recursion var doesn't matter, because the derived implementation will only

View file

@ -33,6 +33,11 @@ test_key_eq! {
v!({ a: v!(U8), b: v!(U8), }), v!({ a: v!(U8), b: v!(U8), }),
v!({ ?a: v!(U8), ?b: v!(U8), }) v!({ ?a: v!(U8), ?b: v!(U8), })
same_tuple:
v!((v!(U8), v!(U16),)), v!((v!(U8), v!(U16),))
same_tuple_fields_diff_types:
v!((v!(U8), v!(U16),)), v!((v!(U32), v!(U64),))
same_tag_union: same_tag_union:
v!([ A v!(U8) v!(STR), B v!(STR) ]), v!([ A v!(U8) v!(STR), B v!(STR) ]) v!([ A v!(U8) v!(STR), B v!(STR) ]), v!([ A v!(U8) v!(STR), B v!(STR) ])
same_tag_union_tags_diff_types: same_tag_union_tags_diff_types:
@ -78,6 +83,9 @@ test_key_neq! {
record_empty_vs_nonempty: record_empty_vs_nonempty:
v!(EMPTY_RECORD), v!({ a: v!(U8), }) v!(EMPTY_RECORD), v!({ a: v!(U8), })
different_tuple_arities:
v!((v!(U8), v!(U16),)), v!((v!(U8), v!(U16), v!(U32),))
different_tag_union_tags: different_tag_union_tags:
v!([ A v!(U8) ]), v!([ B v!(U8) ]) v!([ A v!(U8) ]), v!([ B v!(U8) ])
tag_union_empty_vs_nonempty: tag_union_empty_vs_nonempty: