early return in common tag case

This commit is contained in:
Folkert 2021-07-21 22:02:30 +02:00
parent 05b43c6799
commit 564efd528a

View file

@ -449,18 +449,22 @@ fn unify_tag_union(
let tags1 = rec1.tags;
let tags2 = rec2.tags;
let Separate {
only_in_1: unique_tags1,
only_in_2: unique_tags2,
in_both: shared_tags,
} = separate(tags1, tags2);
let recursion_var = match recursion {
(None, None) => None,
(Some(v), None) | (None, Some(v)) => Some(v),
(Some(v1), Some(_v2)) => Some(v1),
};
if tags1.len() == 1 && tags2.len() == 1 && tags1 == tags2 {
return unify_shared_tags_merge(subs, ctx, tags1, rec1.ext, recursion_var);
}
let Separate {
only_in_1: unique_tags1,
only_in_2: unique_tags2,
in_both: shared_tags,
} = separate(tags1, tags2);
if unique_tags1.is_empty() {
if unique_tags2.is_empty() {
let ext_problems = unify_pool(subs, pool, rec1.ext, rec2.ext);
@ -724,8 +728,8 @@ fn unify_tag_union_not_recursive_recursive(
/// into it.
#[allow(dead_code)]
fn is_structure(var: Variable, subs: &mut Subs) -> bool {
match subs.get(var).content {
Content::Alias(_, _, actual) => is_structure(actual, subs),
match subs.get_content_without_compacting(var) {
Content::Alias(_, _, actual) => is_structure(*actual, subs),
Content::Structure(_) => true,
_ => false,
}
@ -875,6 +879,8 @@ fn unify_shared_tags(
}
if num_shared_tags == matching_tags.len() {
let mut new_tags = matching_tags;
// merge fields from the ext_var into this tag union
let mut fields = Vec::new();
let new_ext_var = match roc_types::pretty_print::chase_ext_tag_union(subs, ext, &mut fields)
@ -882,8 +888,7 @@ fn unify_shared_tags(
Ok(()) => Variable::EMPTY_TAG_UNION,
Err((new, _)) => new,
};
let mut new_tags = matching_tags;
new_tags.extend(fields.into_iter());
match other_tags {
OtherTags::Empty => {}
@ -893,16 +898,7 @@ fn unify_shared_tags(
}
}
new_tags.extend(fields.into_iter());
let flat_type = if let Some(rec) = recursion_var {
debug_assert!(is_recursion_var(subs, rec));
FlatType::RecursiveTagUnion(rec, new_tags, new_ext_var)
} else {
FlatType::TagUnion(new_tags, new_ext_var)
};
merge(subs, ctx, Structure(flat_type))
unify_shared_tags_merge(subs, ctx, new_tags, new_ext_var, recursion_var)
} else {
mismatch!(
"Problem with Tag Union\nThere should be {:?} matching tags, but I only got \n{:?}",
@ -912,6 +908,23 @@ fn unify_shared_tags(
}
}
fn unify_shared_tags_merge(
subs: &mut Subs,
ctx: &Context,
new_tags: MutMap<TagName, Vec<Variable>>,
new_ext_var: Variable,
recursion_var: Option<Variable>,
) -> Outcome {
let flat_type = if let Some(rec) = recursion_var {
debug_assert!(is_recursion_var(subs, rec));
FlatType::RecursiveTagUnion(rec, new_tags, new_ext_var)
} else {
FlatType::TagUnion(new_tags, new_ext_var)
};
merge(subs, ctx, Structure(flat_type))
}
fn has_only_optional_fields<'a, I, T>(fields: &mut I) -> bool
where
I: Iterator<Item = &'a RecordField<T>>,
@ -1069,8 +1082,8 @@ fn unify_flat_type(
if tag_name_1 == tag_name_2 {
let problems = unify_pool(subs, pool, *ext_1, *ext_2);
if problems.is_empty() {
let desc = subs.get(ctx.second);
merge(subs, ctx, desc.content)
let content = subs.get_content_without_compacting(ctx.second).clone();
merge(subs, ctx, content)
} else {
problems
}
@ -1292,19 +1305,25 @@ fn fresh(subs: &mut Subs, pool: &mut Pool, ctx: &Context, content: Content) -> V
fn gather_tags(
subs: &mut Subs,
tags: MutMap<TagName, Vec<Variable>>,
mut tags: MutMap<TagName, Vec<Variable>>,
var: Variable,
) -> TagUnionStructure {
use roc_types::subs::Content::*;
use roc_types::subs::FlatType::*;
match subs.get(var).content {
match subs.get_content_without_compacting(var) {
Structure(TagUnion(sub_tags, sub_ext)) => {
gather_tags(subs, union(tags, &sub_tags), sub_ext)
for (k, v) in sub_tags {
tags.insert(k.clone(), v.clone());
}
let sub_ext = *sub_ext;
gather_tags(subs, tags, sub_ext)
}
Alias(_, _, var) => {
// TODO according to elm/compiler: "TODO may be dropping useful alias info here"
let var = *var;
gather_tags(subs, tags, var)
}
@ -1314,7 +1333,7 @@ fn gather_tags(
fn is_recursion_var(subs: &Subs, var: Variable) -> bool {
matches!(
subs.get_without_compacting(var).content,
subs.get_content_without_compacting(var),
Content::RecursionVar { .. }
)
}