mirror of
https://github.com/roc-lang/roc.git
synced 2025-07-25 15:33:47 +00:00
Correctly check mutual functional recursion between opaque types
The mutual-recursion checks does not admit types that are not function types; because Roc is strict, only functional values can be involved in mutual recursion. However, this check was exercised by checking the head constructor of a type, which is not the correct way to do it. Aliases and opaque types may in fact be function types as well, so we must chase their actual contents. Closes #4246
This commit is contained in:
parent
25d60d20cd
commit
d9863cbbaa
2 changed files with 32 additions and 2 deletions
|
@ -1522,8 +1522,9 @@ fn solve(
|
|||
|
||||
symbols.iter().any(|(s, _)| {
|
||||
let var = env.get_var_by_symbol(s).expect("Symbol not solved!");
|
||||
let content = subs.get_content_without_compacting(var);
|
||||
!matches!(content, Error | Structure(FlatType::Func(..)))
|
||||
let (_, underlying_content) = chase_alias_content(subs, var);
|
||||
|
||||
!matches!(underlying_content, Error | Structure(FlatType::Func(..)))
|
||||
})
|
||||
};
|
||||
|
||||
|
@ -1555,6 +1556,17 @@ fn solve(
|
|||
state
|
||||
}
|
||||
|
||||
fn chase_alias_content(subs: &Subs, mut var: Variable) -> (Variable, &Content) {
|
||||
loop {
|
||||
match subs.get_content_without_compacting(var) {
|
||||
Content::Alias(_, _, real_var, _) => {
|
||||
var = *real_var;
|
||||
}
|
||||
content => return (var, content),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn compact_lambdas_and_check_obligations(
|
||||
arena: &Bump,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue