mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-28 22:34:45 +00:00
remove ATTR_ATTR usage
This commit is contained in:
parent
fa7dec2997
commit
62da85cc06
7 changed files with 37 additions and 265 deletions
|
@ -1,7 +1,6 @@
|
|||
use roc_can::constraint::Constraint::{self, *};
|
||||
use roc_can::expected::{Expected, PExpected};
|
||||
use roc_collections::all::{ImMap, MutMap};
|
||||
use roc_module::ident::TagName;
|
||||
use roc_module::symbol::Symbol;
|
||||
use roc_region::all::{Located, Region};
|
||||
use roc_types::solved_types::Solved;
|
||||
|
@ -872,98 +871,39 @@ fn check_for_infinite_type(
|
|||
) {
|
||||
let var = loc_var.value;
|
||||
|
||||
let is_uniq_infer = matches!(
|
||||
subs.get_ref(var).content,
|
||||
Content::Alias(Symbol::ATTR_ATTR, _, _)
|
||||
);
|
||||
|
||||
while let Some((recursive, chain)) = subs.occurs(var) {
|
||||
while let Some((recursive, _chain)) = subs.occurs(var) {
|
||||
let description = subs.get(recursive);
|
||||
let content = description.content;
|
||||
|
||||
// try to make a tag union recursive, see if that helps
|
||||
match content {
|
||||
Content::Structure(FlatType::TagUnion(tags, ext_var)) => {
|
||||
if !is_uniq_infer {
|
||||
let rec_var = subs.fresh_unnamed_flex_var();
|
||||
subs.set_rank(rec_var, description.rank);
|
||||
subs.set_content(
|
||||
rec_var,
|
||||
Content::RecursionVar {
|
||||
opt_name: None,
|
||||
structure: recursive,
|
||||
},
|
||||
);
|
||||
let rec_var = subs.fresh_unnamed_flex_var();
|
||||
subs.set_rank(rec_var, description.rank);
|
||||
subs.set_content(
|
||||
rec_var,
|
||||
Content::RecursionVar {
|
||||
opt_name: None,
|
||||
structure: recursive,
|
||||
},
|
||||
);
|
||||
|
||||
let mut new_tags = MutMap::default();
|
||||
let mut new_tags = MutMap::default();
|
||||
|
||||
for (label, args) in &tags {
|
||||
let new_args: Vec<_> = args
|
||||
.iter()
|
||||
.map(|var| subs.explicit_substitute(recursive, rec_var, *var))
|
||||
.collect();
|
||||
for (label, args) in &tags {
|
||||
let new_args: Vec<_> = args
|
||||
.iter()
|
||||
.map(|var| subs.explicit_substitute(recursive, rec_var, *var))
|
||||
.collect();
|
||||
|
||||
new_tags.insert(label.clone(), new_args);
|
||||
}
|
||||
|
||||
let new_ext_var = subs.explicit_substitute(recursive, rec_var, ext_var);
|
||||
|
||||
let flat_type = FlatType::RecursiveTagUnion(rec_var, new_tags, new_ext_var);
|
||||
|
||||
subs.set_content(recursive, Content::Structure(flat_type));
|
||||
} else {
|
||||
// Sometimes, the recursion "starts" at the tag-union, not an `Attr`. Here we
|
||||
// We use the path that `occurs` took to find the recursion to go one step
|
||||
// forward in the recursion and find the `Attr` there.
|
||||
let index = 0;
|
||||
match subs.get(chain[index]).content {
|
||||
Content::Structure(FlatType::Apply(Symbol::ATTR_ATTR, args)) => {
|
||||
debug_assert!(args.len() == 2);
|
||||
debug_assert!(
|
||||
subs.get_root_key_without_compacting(recursive)
|
||||
== subs.get_root_key_without_compacting(args[1])
|
||||
);
|
||||
|
||||
// NOTE this ensures we use the same uniqueness var for the whole spine
|
||||
// that might add too much uniqueness restriction.
|
||||
// using `subs.fresh_unnamed_flex_var()` loosens it.
|
||||
let uniq_var = args[0];
|
||||
let tag_union_var = recursive;
|
||||
let recursive = chain[index];
|
||||
|
||||
correct_recursive_attr(
|
||||
subs,
|
||||
recursive,
|
||||
uniq_var,
|
||||
tag_union_var,
|
||||
ext_var,
|
||||
description.rank,
|
||||
&tags,
|
||||
);
|
||||
}
|
||||
_ => circular_error(subs, problems, symbol, &loc_var),
|
||||
}
|
||||
}
|
||||
}
|
||||
Content::Structure(FlatType::Apply(Symbol::ATTR_ATTR, args)) => {
|
||||
debug_assert!(args.len() == 2);
|
||||
let uniq_var = args[0];
|
||||
let tag_union_var = args[1];
|
||||
let nested_description = subs.get(tag_union_var);
|
||||
match nested_description.content {
|
||||
Content::Structure(FlatType::TagUnion(tags, ext_var)) => {
|
||||
correct_recursive_attr(
|
||||
subs,
|
||||
recursive,
|
||||
uniq_var,
|
||||
tag_union_var,
|
||||
ext_var,
|
||||
description.rank,
|
||||
&tags,
|
||||
);
|
||||
}
|
||||
_ => circular_error(subs, problems, symbol, &loc_var),
|
||||
new_tags.insert(label.clone(), new_args);
|
||||
}
|
||||
|
||||
let new_ext_var = subs.explicit_substitute(recursive, rec_var, ext_var);
|
||||
|
||||
let flat_type = FlatType::RecursiveTagUnion(rec_var, new_tags, new_ext_var);
|
||||
|
||||
subs.set_content(recursive, Content::Structure(flat_type));
|
||||
}
|
||||
|
||||
_other => circular_error(subs, problems, symbol, &loc_var),
|
||||
|
@ -971,54 +911,6 @@ fn check_for_infinite_type(
|
|||
}
|
||||
}
|
||||
|
||||
fn content_attr(u: Variable, a: Variable) -> Content {
|
||||
Content::Structure(FlatType::Apply(Symbol::ATTR_ATTR, vec![u, a]))
|
||||
}
|
||||
|
||||
fn correct_recursive_attr(
|
||||
subs: &mut Subs,
|
||||
recursive: Variable,
|
||||
uniq_var: Variable,
|
||||
tag_union_var: Variable,
|
||||
ext_var: Variable,
|
||||
recursion_var_rank: Rank,
|
||||
tags: &MutMap<TagName, Vec<Variable>>,
|
||||
) {
|
||||
let rec_var = subs.fresh_unnamed_flex_var();
|
||||
let attr_var = subs.fresh_unnamed_flex_var();
|
||||
|
||||
let content = content_attr(uniq_var, rec_var);
|
||||
subs.set_content(attr_var, content);
|
||||
|
||||
subs.set_rank(rec_var, recursion_var_rank);
|
||||
subs.set_content(
|
||||
rec_var,
|
||||
Content::RecursionVar {
|
||||
opt_name: None,
|
||||
structure: recursive,
|
||||
},
|
||||
);
|
||||
|
||||
let mut new_tags = MutMap::default();
|
||||
|
||||
let new_ext_var = subs.explicit_substitute(recursive, attr_var, ext_var);
|
||||
for (label, args) in tags {
|
||||
let new_args: Vec<_> = args
|
||||
.iter()
|
||||
.map(|var| subs.explicit_substitute(recursive, attr_var, *var))
|
||||
.collect();
|
||||
|
||||
new_tags.insert(label.clone(), new_args);
|
||||
}
|
||||
|
||||
let new_tag_type = FlatType::RecursiveTagUnion(rec_var, new_tags, new_ext_var);
|
||||
subs.set_content(tag_union_var, Content::Structure(new_tag_type));
|
||||
|
||||
let new_recursive = content_attr(uniq_var, tag_union_var);
|
||||
|
||||
subs.set_content(recursive, new_recursive);
|
||||
}
|
||||
|
||||
fn circular_error(
|
||||
subs: &mut Subs,
|
||||
problems: &mut Vec<TypeError>,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue