Recursive vars in occurs check can happen anywhere in the chain

This commit is contained in:
Ayaz Hafiz 2022-08-09 16:07:59 -07:00
parent f20d1ac59a
commit 3f1e11f920
No known key found for this signature in database
GPG key ID: 0E2A37416A25EF58

View file

@ -2876,28 +2876,34 @@ fn check_for_infinite_type(
) {
let var = loc_var.value;
while let Err((recursive, _chain)) = subs.occurs(var) {
// try to make a union recursive, see if that helps
match subs.get_content_without_compacting(recursive) {
&Content::Structure(FlatType::TagUnion(tags, ext_var)) => {
subs.mark_tag_union_recursive(recursive, tags, ext_var);
}
&Content::LambdaSet(subs::LambdaSet {
solved,
recursion_var: _,
unspecialized,
ambient_function: ambient_function_var,
}) => {
subs.mark_lambda_set_recursive(
recursive,
'next_occurs_check: while let Err((_, chain)) = subs.occurs(var) {
// 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 &var in chain.iter().rev() {
match subs.get_content_without_compacting(var) {
&Content::Structure(FlatType::TagUnion(tags, ext_var)) => {
subs.mark_tag_union_recursive(var, tags, ext_var);
continue 'next_occurs_check;
}
&Content::LambdaSet(subs::LambdaSet {
solved,
recursion_var: _,
unspecialized,
ambient_function_var,
);
ambient_function: ambient_function_var,
}) => {
subs.mark_lambda_set_recursive(
var,
solved,
unspecialized,
ambient_function_var,
);
continue 'next_occurs_check;
}
_ => { /* fall through */ }
}
_other => circular_error(subs, problems, symbol, &loc_var),
}
circular_error(subs, problems, symbol, &loc_var);
}
}