diff --git a/cli_utils/Cargo.lock b/cli_utils/Cargo.lock index dcd01f8c6a..f79e63f0bd 100644 --- a/cli_utils/Cargo.lock +++ b/cli_utils/Cargo.lock @@ -191,6 +191,18 @@ dependencies = [ "typenum", ] +[[package]] +name = "bitvec" +version = "0.22.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5237f00a8c86130a0cc317830e558b966dd7850d48a953d998c813f01a41b527" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] + [[package]] name = "block" version = "0.1.6" @@ -968,6 +980,12 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2022715d62ab30faffd124d40b76f4134a550a87792276512b18d63272333394" +[[package]] +name = "funty" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1847abb9cb65d566acd5942e94aea9c8f547ad02c98e1649326fc0e8910b8b1e" + [[package]] name = "futures" version = "0.3.17" @@ -1919,6 +1937,28 @@ dependencies = [ "ttf-parser 0.13.2", ] +[[package]] +name = "packed_struct" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c48e482b9a59ad6c2cdb06f7725e7bd33fe3525baaf4699fde7bfea6a5b77b1" +dependencies = [ + "bitvec", + "packed_struct_codegen", + "serde", +] + +[[package]] +name = "packed_struct_codegen" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56e3692b867ec1d48ccb441e951637a2cc3130d0912c0059e48319e1c83e44bc" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "page_size" version = "0.4.2" @@ -2210,6 +2250,12 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "radium" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "643f8f41a8ebc4c5dc4515c82bb8abd397b527fc20fd681b7c011c2aee5d44fb" + [[package]] name = "rand" version = "0.8.4" @@ -2603,6 +2649,7 @@ version = "0.1.0" dependencies = [ "bumpalo", "object 0.26.2", + "packed_struct", "roc_builtins", "roc_collections", "roc_module", @@ -2771,6 +2818,7 @@ dependencies = [ name = "roc_solve" version = "0.1.0" dependencies = [ + "bumpalo", "roc_can", "roc_collections", "roc_module", @@ -2787,6 +2835,7 @@ version = "0.1.0" name = "roc_types" version = "0.1.0" dependencies = [ + "bumpalo", "roc_collections", "roc_module", "roc_region", @@ -3163,6 +3212,12 @@ dependencies = [ "unicode-xid", ] +[[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + [[package]] name = "target-lexicon" version = "0.12.2" @@ -3807,6 +3862,15 @@ dependencies = [ "rand_core 0.6.3", ] +[[package]] +name = "wyz" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "129e027ad65ce1453680623c3fb5163cbf7107bfe1aa32257e7d0e63f9ced188" +dependencies = [ + "tap", +] + [[package]] name = "x11-clipboard" version = "0.5.3" diff --git a/compiler/mono/src/layout_soa.rs b/compiler/mono/src/layout_soa.rs index 828f6a42f0..19a7116c43 100644 --- a/compiler/mono/src/layout_soa.rs +++ b/compiler/mono/src/layout_soa.rs @@ -9,7 +9,7 @@ use std::collections::hash_map::Entry; #[cfg(debug_assertions)] use crate::layout::{ext_var_is_empty_record, ext_var_is_empty_tag_union}; -#[derive(Clone, Copy)] +#[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct Index { index: u32, _marker: std::marker::PhantomData, @@ -24,7 +24,7 @@ impl Index { } } -#[derive(Clone, Copy)] +#[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct Slice { start: u32, length: u16, @@ -347,7 +347,7 @@ impl LambdaSet { } } -#[derive(Clone, Copy)] +#[derive(Debug, Clone, Copy, PartialEq)] pub enum Layout { // theory: we can zero out memory to reserve space for many layouts Reserved, @@ -401,7 +401,30 @@ fn round_up_to_alignment(unaligned: u16, alignment_bytes: u16) -> u16 { impl Layouts { const VOID_INDEX: Index = Index::new(0); - // const UNIT_INDEX: Index = Index::new(1); + const VOID_TUPLE: Index<(Layout, Layout)> = Index::new(0); + const UNIT_INDEX: Index = Index::new(2); + + pub fn new(usize_int_width: IntWidth) -> Self { + let mut layouts = Vec::with_capacity(64); + + layouts.push(Layout::VOID); + layouts.push(Layout::VOID); + layouts.push(Layout::UNIT); + + // sanity check + debug_assert_eq!(layouts[Self::VOID_INDEX.index as usize], Layout::VOID); + debug_assert_eq!(layouts[Self::VOID_TUPLE.index as usize + 1], Layout::VOID); + debug_assert_eq!(layouts[Self::UNIT_INDEX.index as usize], Layout::UNIT); + + Layouts { + layouts: Vec::default(), + layout_slices: Vec::default(), + lambda_sets: Vec::default(), + symbols: Vec::default(), + recursion_variable_to_structure_variable_map: MutMap::default(), + usize_int_width, + } + } /// sort a slice according to elements' alignment fn sort_slice_by_alignment(&mut self, layout_slice: Slice) { @@ -539,6 +562,8 @@ impl Layout { pub const VOID: Self = Self::UnionNonRecursive(Slice::new(0, 0)); pub const EMPTY_LIST: Self = Self::List(Layouts::VOID_INDEX); + pub const EMPTY_DICT: Self = Self::Dict(Layouts::VOID_TUPLE); + pub const EMPTY_SET: Self = Self::Set(Layouts::VOID_INDEX); pub fn from_var( layouts: &mut Layouts, @@ -558,6 +583,19 @@ impl Layout { Self::from_content(layouts, subs, var, content) } + fn from_var_help_or_void( + layouts: &mut Layouts, + subs: &Subs, + var: Variable, + ) -> Result { + let content = &subs.get_ref(var).content; + match Self::from_content(layouts, subs, var, content) { + Ok(layout) => Ok(layout), + Err(LayoutError::UnresolvedVariable(_)) => Ok(Layout::VOID), + Err(other) => Err(other), + } + } + fn from_content( layouts: &mut Layouts, subs: &Subs, @@ -640,16 +678,40 @@ impl Layout { debug_assert_eq!(arguments.len(), 1); let element_var = subs.variables[arguments.slice.start as usize]; - match Self::from_var_help(layouts, subs, element_var) { - Ok(element_layout) => { - let element_index = Index::new(layouts.layouts.len() as _); - layouts.layouts.push(element_layout); + let element_layout = Self::from_var_help_or_void(layouts, subs, element_var)?; - Ok(Layout::List(element_index)) - } - Err(UnresolvedVariable(_)) => Ok(Layout::EMPTY_LIST), - Err(other) => Err(other), - } + let element_index = Index::new(layouts.layouts.len() as _); + layouts.layouts.push(element_layout); + + Ok(Layout::List(element_index)) + } + + FlatType::Apply(Symbol::DICT_DICT, arguments) => { + debug_assert_eq!(arguments.len(), 2); + + let key_var = subs.variables[arguments.slice.start as usize]; + let value_var = subs.variables[arguments.slice.start as usize + 1]; + + let key_layout = Self::from_var_help_or_void(layouts, subs, key_var)?; + let value_layout = Self::from_var_help_or_void(layouts, subs, value_var)?; + + let index = Index::new(layouts.layouts.len() as _); + layouts.layouts.push(key_layout); + layouts.layouts.push(value_layout); + + Ok(Layout::Dict(index)) + } + + FlatType::Apply(Symbol::SET_SET, arguments) => { + debug_assert_eq!(arguments.len(), 1); + + let element_var = subs.variables[arguments.slice.start as usize]; + let element_layout = Self::from_var_help_or_void(layouts, subs, element_var)?; + + let element_index = Index::new(layouts.layouts.len() as _); + layouts.layouts.push(element_layout); + + Ok(Layout::Set(element_index)) } FlatType::Apply(symbol, _) => {