mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-01 15:51:12 +00:00
Simplify maybe_mark_union_recursive
This commit is contained in:
parent
2f29326e7a
commit
0fa4aa8cbd
2 changed files with 39 additions and 42 deletions
|
@ -1758,10 +1758,20 @@ impl Subs {
|
||||||
self.utable.is_redirect(var)
|
self.utable.is_redirect(var)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Determines if there is any variable in [var] that occurs recursively.
|
||||||
|
///
|
||||||
|
/// The [Err] variant returns the occuring variable and the chain of variables that led
|
||||||
|
/// to a recursive occurence, in order of proximity. For example, if the type "r" has a
|
||||||
|
/// reference chain r -> t1 -> t2 -> r, [occurs] will return `Err(r, [t2, t1, r])`.
|
||||||
|
///
|
||||||
|
/// This ignores [Content::RecursionVar]s that occur recursively, because those are
|
||||||
|
/// already priced in and expected to occur. Use [Subs::occurs_including_recursion_vars] if you
|
||||||
|
/// need to check for recursion var occurence.
|
||||||
pub fn occurs(&self, var: Variable) -> Result<(), (Variable, Vec<Variable>)> {
|
pub fn occurs(&self, var: Variable) -> Result<(), (Variable, Vec<Variable>)> {
|
||||||
occurs(self, &[], var, false)
|
occurs(self, &[], var, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Like [Subs::occurs], but also errors when recursion vars occur.
|
||||||
pub fn occurs_including_recursion_vars(
|
pub fn occurs_including_recursion_vars(
|
||||||
&self,
|
&self,
|
||||||
var: Variable,
|
var: Variable,
|
||||||
|
|
|
@ -1528,32 +1528,21 @@ enum OtherTags2 {
|
||||||
/// Promotes a non-recursive tag union or lambda set to its recursive variant, if it is found to be
|
/// Promotes a non-recursive tag union or lambda set to its recursive variant, if it is found to be
|
||||||
/// recursive.
|
/// recursive.
|
||||||
fn maybe_mark_union_recursive(subs: &mut Subs, union_var: Variable) {
|
fn maybe_mark_union_recursive(subs: &mut Subs, union_var: Variable) {
|
||||||
'outer: while let Err((recursive, chain)) = subs.occurs(union_var) {
|
'outer: while let Err((_, chain)) = subs.occurs(union_var) {
|
||||||
let description = subs.get(recursive);
|
// walk the chain till we find a tag union or lambda set, starting from the variable that
|
||||||
|
// occurred recursively, which is always at the end of the chain.
|
||||||
|
for &v in chain.iter().rev() {
|
||||||
|
let description = subs.get(v);
|
||||||
match description.content {
|
match description.content {
|
||||||
Content::Structure(FlatType::TagUnion(tags, ext_var)) => {
|
Content::Structure(FlatType::TagUnion(tags, ext_var)) => {
|
||||||
subs.mark_tag_union_recursive(recursive, tags, ext_var);
|
subs.mark_tag_union_recursive(v, tags, ext_var);
|
||||||
}
|
|
||||||
LambdaSet(self::LambdaSet {
|
|
||||||
solved,
|
|
||||||
recursion_var: OptVariable::NONE,
|
|
||||||
}) => {
|
|
||||||
subs.mark_lambda_set_recursive(recursive, solved);
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
// walk the chain till we find a tag union or lambda set
|
|
||||||
for v in &chain[..chain.len() - 1] {
|
|
||||||
let description = subs.get(*v);
|
|
||||||
match description.content {
|
|
||||||
Content::Structure(FlatType::TagUnion(tags, ext_var)) => {
|
|
||||||
subs.mark_tag_union_recursive(*v, tags, ext_var);
|
|
||||||
continue 'outer;
|
continue 'outer;
|
||||||
}
|
}
|
||||||
LambdaSet(self::LambdaSet {
|
LambdaSet(self::LambdaSet {
|
||||||
solved,
|
solved,
|
||||||
recursion_var: OptVariable::NONE,
|
recursion_var: OptVariable::NONE,
|
||||||
}) => {
|
}) => {
|
||||||
subs.mark_lambda_set_recursive(*v, solved);
|
subs.mark_lambda_set_recursive(v, solved);
|
||||||
continue 'outer;
|
continue 'outer;
|
||||||
}
|
}
|
||||||
_ => { /* fall through */ }
|
_ => { /* fall through */ }
|
||||||
|
@ -1573,8 +1562,6 @@ fn maybe_mark_union_recursive(subs: &mut Subs, union_var: Variable) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn unify_shared_tags_new(
|
fn unify_shared_tags_new(
|
||||||
subs: &mut Subs,
|
subs: &mut Subs,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue