diff --git a/compiler/types/src/subs.rs b/compiler/types/src/subs.rs index 4e078323bf..f6e7a14a81 100644 --- a/compiler/types/src/subs.rs +++ b/compiler/types/src/subs.rs @@ -56,6 +56,7 @@ pub struct Subs { pub tag_names: Vec, pub field_names: Vec, pub record_fields: Vec>, + pub variable_slices: Vec, } /// A slice into the Vec of subs @@ -895,6 +896,43 @@ impl IntoIterator for VariableSubsSlice { } } +#[derive(Clone, Copy, Debug)] +pub struct UnionTags { + pub tag_names: SubsSlice, + pub variables: SubsSlice, +} + +impl UnionTags { + pub fn insert_into_subs<'a, I>(subs: &mut Subs, input: I) -> Self + where + I: IntoIterator, + { + let tag_names_start = subs.tag_names.len() as u32; + let variables_start = subs.variable_slices.len() as u32; + + let it = input.into_iter(); + let size_hint = it.size_hint().0; + + subs.tag_names.reserve(size_hint); + subs.variable_slices.reserve(size_hint); + + let mut length = 0; + for (k, v) in it { + let variables = VariableSubsSlice::insert_into_subs(subs, v.iter().copied()); + + subs.tag_names.push(k); + subs.variable_slices.push(variables); + + length += 1; + } + + UnionTags { + variables: SubsSlice::new(variables_start, length), + tag_names: SubsSlice::new(tag_names_start, length), + } + } +} + #[derive(Clone, Copy, Debug)] pub struct RecordFields { pub length: u16,