mirror of
https://github.com/roc-lang/roc.git
synced 2025-07-23 14:35:12 +00:00
Force occurs check for introduced types after checking annotated bodies
The current type inference scheme is such that we first introduce the types for annotation functions, then check their bodies without additional re-generalization. As part of generalization, we also perform occurs checks to fix-up recursive tag unions. However, type annotations can contain type inference variables that are neither part of the generalization scheme, nor are re-generalized later on, and in fact end up forming a closure of a recursive type. If we do not catch and break such closures into recursive types, things go bad soon after in later stages of the compiler. To deal with this, re-introduce the values of recursive values after we check their definitions, forcing an occurs check. This introduction is benign because we already generalized appropriate type variables anyway. Though, the introduction is somewhat unnecessary, and I have ideas on how to make all of this simpler and more performant. That will come in the future.
This commit is contained in:
parent
40da261dfd
commit
dce4d6c4c7
2 changed files with 30 additions and 1 deletions
|
@ -8336,4 +8336,20 @@ mod solve_expr {
|
|||
"###
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn solve_inference_var_in_annotation_requiring_recursion_fix() {
|
||||
infer_queries!(indoc!(
|
||||
r#"
|
||||
app "test" provides [translateStatic] to "./platform"
|
||||
|
||||
translateStatic : _ -> _
|
||||
translateStatic = \Element c ->
|
||||
#^^^^^^^^^^^^^^^{-1}
|
||||
Element (List.map c translateStatic)
|
||||
"#
|
||||
),
|
||||
@"translateStatic : [Element (List a)] as a -[[translateStatic(0)]]-> [Element (List b)]* as b"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue