diff --git a/crates/compiler/solve/tests/solve_expr.rs b/crates/compiler/solve/tests/solve_expr.rs index 3ca24cbe93..74e72ff688 100644 --- a/crates/compiler/solve/tests/solve_expr.rs +++ b/crates/compiler/solve/tests/solve_expr.rs @@ -8197,4 +8197,27 @@ mod solve_expr { "### ); } + + #[test] + fn fix_recursion_under_alias_issue_4368() { + infer_eq_without_problem( + indoc!( + r#" + app "test" provides [doIt] to "./platform" + + Effect : [ + DoIt {} ({} -> Effect), + ] + + Task := ({} -> Effect) -> Effect + + doIt : {} -> Task + doIt = \{} -> + @Task \toNext -> + DoIt {} \{} -> (toNext {}) + "# + ), + "{} -> Task", + ) + } } diff --git a/crates/compiler/types/src/subs.rs b/crates/compiler/types/src/subs.rs index 50784290ec..381011123c 100644 --- a/crates/compiler/types/src/subs.rs +++ b/crates/compiler/types/src/subs.rs @@ -3255,13 +3255,17 @@ fn occurs( EmptyRecord | EmptyTagUnion => Ok(()), } } - Alias(_, args, _, _) => { + Alias(_, args, real_var, _) => { let mut new_seen = seen.to_owned(); new_seen.push(root_var); for var_index in args.into_iter() { let var = subs[var_index]; - short_circuit_help(subs, root_var, &new_seen, var)?; + if short_circuit_help(subs, root_var, &new_seen, var).is_err() { + // Pay the cost and figure out what the actual recursion point is + + return short_circuit_help(subs, root_var, &new_seen, *real_var); + } } Ok(())