mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-28 14:24:45 +00:00
intern common tag names
This commit is contained in:
parent
00ef997be3
commit
38c2710fc5
2 changed files with 62 additions and 21 deletions
|
@ -1850,6 +1850,29 @@ fn find_tag_name_run<T>(slice: &[(TagName, T)], subs: &mut Subs) -> Option<SubsS
|
|||
result
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn register_tag_arguments<'a>(
|
||||
subs: &mut Subs,
|
||||
rank: Rank,
|
||||
pools: &mut Pools,
|
||||
arena: &'_ bumpalo::Bump,
|
||||
stack: &mut bumpalo::collections::Vec<'_, TypeToVar<'a>>,
|
||||
arguments: &'a [Type],
|
||||
) -> VariableSubsSlice {
|
||||
if arguments.is_empty() {
|
||||
VariableSubsSlice::default()
|
||||
} else {
|
||||
let new_variables = VariableSubsSlice::reserve_into_subs(subs, arguments.len());
|
||||
let it = (new_variables.indices()).zip(arguments);
|
||||
for (target_index, argument) in it {
|
||||
let var = RegisterVariable::with_stack(subs, rank, pools, arena, argument, stack);
|
||||
subs.variables[target_index] = var;
|
||||
}
|
||||
|
||||
new_variables
|
||||
}
|
||||
}
|
||||
|
||||
/// Assumes that the tags are sorted and there are no duplicates!
|
||||
fn insert_tags_fast_path<'a>(
|
||||
subs: &mut Subs,
|
||||
|
@ -1859,23 +1882,35 @@ fn insert_tags_fast_path<'a>(
|
|||
tags: &'a [(TagName, Vec<Type>)],
|
||||
stack: &mut bumpalo::collections::Vec<'_, TypeToVar<'a>>,
|
||||
) -> UnionTags {
|
||||
let new_variable_slices = SubsSlice::reserve_variable_slices(subs, tags.len());
|
||||
if let [(TagName::Global(tag_name), arguments)] = tags {
|
||||
let variable_slice = register_tag_arguments(subs, rank, pools, arena, stack, arguments);
|
||||
let new_variable_slices =
|
||||
SubsSlice::extend_new(&mut subs.variable_slices, [variable_slice]);
|
||||
|
||||
macro_rules! subs_tag_name {
|
||||
($tag_name_slice:expr) => {
|
||||
return UnionTags::from_slices($tag_name_slice, new_variable_slices)
|
||||
};
|
||||
}
|
||||
|
||||
match tag_name.as_str() {
|
||||
"Ok" => subs_tag_name!(Subs::TAG_NAME_OK.as_slice()),
|
||||
"Err" => subs_tag_name!(Subs::TAG_NAME_ERR.as_slice()),
|
||||
"InvalidNumStr" => subs_tag_name!(Subs::TAG_NAME_INVALID_NUM_STR.as_slice()),
|
||||
"BadUtf8" => subs_tag_name!(Subs::TAG_NAME_BAD_UTF_8.as_slice()),
|
||||
"OutOfBounds" => subs_tag_name!(Subs::TAG_NAME_OUT_OF_BOUNDS.as_slice()),
|
||||
_other => {}
|
||||
}
|
||||
}
|
||||
|
||||
let new_variable_slices = SubsSlice::reserve_variable_slices(subs, tags.len());
|
||||
match find_tag_name_run(tags, subs) {
|
||||
Some(new_tag_names) => {
|
||||
let it = (new_variable_slices.indices()).zip(tags);
|
||||
|
||||
for (variable_slice_index, (_, arguments)) in it {
|
||||
// turn the arguments into variables
|
||||
let new_variables = VariableSubsSlice::reserve_into_subs(subs, arguments.len());
|
||||
let it = (new_variables.indices()).zip(arguments);
|
||||
for (target_index, argument) in it {
|
||||
let var =
|
||||
RegisterVariable::with_stack(subs, rank, pools, arena, argument, stack);
|
||||
subs.variables[target_index] = var;
|
||||
}
|
||||
|
||||
subs.variable_slices[variable_slice_index] = new_variables;
|
||||
subs.variable_slices[variable_slice_index] =
|
||||
register_tag_arguments(subs, rank, pools, arena, stack, arguments);
|
||||
}
|
||||
|
||||
UnionTags::from_slices(new_tag_names, new_variable_slices)
|
||||
|
@ -1888,16 +1923,9 @@ fn insert_tags_fast_path<'a>(
|
|||
.zip(tags);
|
||||
|
||||
for ((variable_slice_index, tag_name_index), (tag_name, arguments)) in it {
|
||||
// turn the arguments into variables
|
||||
let new_variables = VariableSubsSlice::reserve_into_subs(subs, arguments.len());
|
||||
let it = (new_variables.indices()).zip(arguments);
|
||||
for (target_index, argument) in it {
|
||||
let var =
|
||||
RegisterVariable::with_stack(subs, rank, pools, arena, argument, stack);
|
||||
subs.variables[target_index] = var;
|
||||
}
|
||||
subs.variable_slices[variable_slice_index] =
|
||||
register_tag_arguments(subs, rank, pools, arena, stack, arguments);
|
||||
|
||||
subs.variable_slices[variable_slice_index] = new_variables;
|
||||
subs.tag_names[tag_name_index] = tag_name.clone();
|
||||
}
|
||||
|
||||
|
|
|
@ -331,7 +331,7 @@ impl SubsSlice<TagName> {
|
|||
}
|
||||
|
||||
impl<T> SubsIndex<T> {
|
||||
pub fn new(start: u32) -> Self {
|
||||
pub const fn new(start: u32) -> Self {
|
||||
Self {
|
||||
index: start,
|
||||
_marker: std::marker::PhantomData,
|
||||
|
@ -345,6 +345,10 @@ impl<T> SubsIndex<T> {
|
|||
|
||||
index
|
||||
}
|
||||
|
||||
pub const fn as_slice(self) -> SubsSlice<T> {
|
||||
SubsSlice::new(self.index, 1)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> IntoIterator for SubsSlice<T> {
|
||||
|
@ -1291,9 +1295,14 @@ fn define_float_types(subs: &mut Subs) {
|
|||
|
||||
impl Subs {
|
||||
pub const RESULT_TAG_NAMES: SubsSlice<TagName> = SubsSlice::new(0, 2);
|
||||
pub const TAG_NAME_ERR: SubsIndex<TagName> = SubsIndex::new(0);
|
||||
pub const TAG_NAME_OK: SubsIndex<TagName> = SubsIndex::new(1);
|
||||
pub const NUM_AT_NUM: SubsSlice<TagName> = SubsSlice::new(2, 1);
|
||||
pub const NUM_AT_INTEGER: SubsSlice<TagName> = SubsSlice::new(3, 1);
|
||||
pub const NUM_AT_FLOATINGPOINT: SubsSlice<TagName> = SubsSlice::new(4, 1);
|
||||
pub const TAG_NAME_INVALID_NUM_STR: SubsIndex<TagName> = SubsIndex::new(5);
|
||||
pub const TAG_NAME_BAD_UTF_8: SubsIndex<TagName> = SubsIndex::new(6);
|
||||
pub const TAG_NAME_OUT_OF_BOUNDS: SubsIndex<TagName> = SubsIndex::new(7);
|
||||
|
||||
pub fn new() -> Self {
|
||||
Self::with_capacity(0)
|
||||
|
@ -1311,6 +1320,10 @@ impl Subs {
|
|||
tag_names.push(TagName::Private(Symbol::NUM_AT_INTEGER));
|
||||
tag_names.push(TagName::Private(Symbol::NUM_AT_FLOATINGPOINT));
|
||||
|
||||
tag_names.push(TagName::Global("InvalidNumStr".into()));
|
||||
tag_names.push(TagName::Global("BadUtf8".into()));
|
||||
tag_names.push(TagName::Global("OutOfBounds".into()));
|
||||
|
||||
let mut subs = Subs {
|
||||
utable: UnificationTable::default(),
|
||||
variables: Vec::new(),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue