Generate glue for Set

This commit is contained in:
Richard Feldman 2022-08-15 13:03:50 -04:00
parent 0f179272d9
commit 0b54f08f7f
No known key found for this signature in database
GPG key ID: F1F21AA5B1D9E43B
5 changed files with 64 additions and 29 deletions

View file

@ -946,15 +946,14 @@ fn add_builtin_type<'a>(
Layout::Struct { field_layouts, .. }, Layout::Struct { field_layouts, .. },
Content::Structure(FlatType::Apply(Symbol::LIST_LIST, args_subs_slice)), Content::Structure(FlatType::Apply(Symbol::LIST_LIST, args_subs_slice)),
) => { ) => {
let (key_var, val_var) = {
let args_tuple = env.subs.get_subs_slice(*args_subs_slice); let args_tuple = env.subs.get_subs_slice(*args_subs_slice);
debug_assert_eq!(args_tuple.len(), 1); debug_assert_eq!(args_tuple.len(), 1);
let (key_var, val_var) =
match env.subs.get_content_without_compacting(args_tuple[0]) { match env.subs.get_content_without_compacting(args_tuple[0]) {
Content::Structure(FlatType::TagUnion(union_tags, ext_var)) => { Content::Structure(FlatType::TagUnion(union_tags, ext_var)) => {
let (mut iter, _) = let (mut iter, _) = union_tags.sorted_iterator_and_ext(env.subs, *ext_var);
union_tags.sorted_iterator_and_ext(env.subs, *ext_var);
let payloads = iter.next().unwrap().1; let payloads = iter.next().unwrap().1;
debug_assert_eq!(iter.next(), None); debug_assert_eq!(iter.next(), None);
@ -964,6 +963,7 @@ fn add_builtin_type<'a>(
_ => { _ => {
unreachable!() unreachable!()
} }
}
}; };
debug_assert_eq!(field_layouts.len(), 2); debug_assert_eq!(field_layouts.len(), 2);
@ -977,14 +977,47 @@ fn add_builtin_type<'a>(
dict_id dict_id
} }
_ => unreachable!("Unrecognized List element for Dict: {:?}", elem_layout), (elem_layout, alias_content) => unreachable!(
"Unrecognized List element for Dict. Layout was: {:?} and alias_content was: {:?}",
elem_layout,
alias_content
),
} }
} }
( (
Builtin::List(_elem_layout), Builtin::List(elem_layout),
Alias(Symbol::SET_SET, _alias_vars, _alias_var, _alias_kind), Alias(Symbol::SET_SET, _alias_vars, alias_var, AliasKind::Opaque),
) => { ) => {
todo!(); match (
elem_layout,
env.subs.get_content_without_compacting(*alias_var),
) {
(
Layout::Struct { field_layouts, .. },
Alias(Symbol::DICT_DICT, alias_args, _alias_var, AliasKind::Opaque),
) => {
let dict_type_vars = env.subs.get_subs_slice(alias_args.type_variables());
debug_assert_eq!(dict_type_vars.len(), 2);
// Sets only use the key of the Dict they wrap, not the value
let elem_var = dict_type_vars[0];
debug_assert_eq!(field_layouts.len(), 2);
let elem_id = add_type_help(env, field_layouts[0], elem_var, opt_name, types);
let set_id = types.add_anonymous(RocType::RocSet(elem_id), layout);
types.depends(set_id, elem_id);
set_id
}
(elem_layout, alias_content) => unreachable!(
"Unrecognized List element for Set. Layout was: {:?} and alias_content was: {:?}",
elem_layout,
alias_content
),
}
} }
(Builtin::List(elem_layout), alias) => { (Builtin::List(elem_layout), alias) => {
unreachable!( unreachable!(

View file

@ -4,6 +4,8 @@ app "app"
provides [main] to pf provides [main] to pf
main = main =
Dict.empty Set.empty
|> Dict.insert "foo" "bar" |> Set.insert "foo"
|> Dict.insert "baz" "blah" |> Set.insert "bar"
|> Set.insert "foo"
|> Set.insert "baz"

View file

@ -5,5 +5,5 @@ platform "test-platform"
imports [] imports []
provides [mainForHost] provides [mainForHost]
mainForHost : Dict Str Str mainForHost : Set Str
mainForHost = main mainForHost = main

View file

@ -1,10 +1,10 @@
mod test_glue; mod test_glue;
use roc_std::{RocDict, RocStr}; use roc_std::{RocSet, RocStr};
extern "C" { extern "C" {
#[link_name = "roc__mainForHost_1_exposed_generic"] #[link_name = "roc__mainForHost_1_exposed_generic"]
fn roc_main(_: *mut RocDict<RocStr, RocStr>); fn roc_main(_: *mut RocSet<RocStr>);
} }
#[no_mangle] #[no_mangle]
@ -12,9 +12,8 @@ pub extern "C" fn rust_main() -> i32 {
use std::cmp::Ordering; use std::cmp::Ordering;
use std::collections::hash_set::HashSet; use std::collections::hash_set::HashSet;
let dict = unsafe { let set = unsafe {
let mut ret: core::mem::MaybeUninit<RocDict<RocStr, RocStr>> = let mut ret: core::mem::MaybeUninit<RocSet<RocStr>> = core::mem::MaybeUninit::uninit();
core::mem::MaybeUninit::uninit();
roc_main(ret.as_mut_ptr()); roc_main(ret.as_mut_ptr());
@ -23,20 +22,21 @@ pub extern "C" fn rust_main() -> i32 {
// Verify that it has all the expected traits. // Verify that it has all the expected traits.
assert!(dict == dict); // PartialEq assert!(set == set); // PartialEq
assert!(dict.clone() == dict.clone()); // Clone assert_eq!(set.len(), 3); // len
assert!(set.clone() == set.clone()); // Clone
assert!(dict.partial_cmp(&dict) == Some(Ordering::Equal)); // PartialOrd assert!(set.partial_cmp(&set) == Some(Ordering::Equal)); // PartialOrd
assert!(dict.cmp(&dict) == Ordering::Equal); // Ord assert!(set.cmp(&set) == Ordering::Equal); // Ord
let mut set = HashSet::new(); let mut hash_set = HashSet::new();
set.insert(dict.clone()); // Eq, Hash hash_set.insert(set.clone()); // Eq, Hash
set.insert(dict.clone()); hash_set.insert(set.clone());
assert_eq!(set.len(), 1); assert_eq!(hash_set.len(), 1);
println!("dict was: {:?}", dict); // Debug println!("set was: {:?}", set); // Debug
// Exit code // Exit code
0 0

View file

@ -74,7 +74,7 @@ mod glue_cli_run {
dict was: RocDict {"foo": "bar", "baz": "blah"} dict was: RocDict {"foo": "bar", "baz": "blah"}
"#), "#),
set:"set" => indoc!(r#" set:"set" => indoc!(r#"
set was: RocSet ["foo", "bar", "baz"] set was: RocSet {"foo", "bar", "baz"}
"#), "#),
enumeration:"enumeration" => "tag_union was: MyEnum::Foo, Bar is: MyEnum::Bar, Baz is: MyEnum::Baz\n", enumeration:"enumeration" => "tag_union was: MyEnum::Foo, Bar is: MyEnum::Bar, Baz is: MyEnum::Baz\n",
union_with_padding:"union-with-padding" => indoc!(r#" union_with_padding:"union-with-padding" => indoc!(r#"