Name resolved type variables during Expr2 constrain testing

Prior to this patch we would not explicitly name solved type variables,
causing the elaborated type to appear unconstrained even when the
internal representation was constrained. For example, given a definition
like

```
\a, b -> Pair a b
```

we would generate distinct, fresh type variables for `a` and `b` but not
name them after solution. So even though the compiler knows they are
distinct, printing to the surface syntax would emit

```
*, * -> [ Pair * * ]*
```

which is incorrect, as the result type is constrained on the input type.
Instead, we now properly emit

```
a, b -> [ Pair a b ]*
```

naming variables where dependencies do exist. Where type variables are
don't constrain anything else, we can and do continue to emit the
wildcard type.
This commit is contained in:
ayazhafiz 2021-11-16 11:44:34 -05:00
parent b03ed18553
commit b824302ab3

View file

@ -1765,7 +1765,7 @@ pub mod test_constrain {
use roc_parse::parser::SyntaxError;
use roc_region::all::Region;
use roc_types::{
pretty_print::content_to_string,
pretty_print::{content_to_string, name_all_type_vars},
solved_types::Solved,
subs::{Subs, VarStore, Variable},
};
@ -1876,6 +1876,9 @@ pub mod test_constrain {
let subs = solved.inner_mut();
// name type vars
name_all_type_vars(var, subs);
let content = subs.get_content_without_compacting(var);
// Connect the ModuleId to it's IdentIds
@ -2132,6 +2135,102 @@ pub mod test_constrain {
)
}
#[test]
fn dual_arity_lambda() {
infer_eq(
indoc!(
r#"
\a, b -> Pair a b
"#
),
"a, b -> [ Pair a b ]*",
);
}
#[test]
fn anonymous_identity() {
infer_eq(
indoc!(
r#"
(\a -> a) 3.14
"#
),
"Float *",
);
}
#[test]
fn identity_of_identity() {
infer_eq(
indoc!(
r#"
(\val -> val) (\val -> val)
"#
),
"a -> a",
);
}
#[test]
fn identity_function() {
infer_eq(
indoc!(
r#"
\val -> val
"#
),
"a -> a",
);
}
#[test]
fn apply_function() {
infer_eq(
indoc!(
r#"
\f, x -> f x
"#
),
"(a -> b), a -> b",
);
}
#[test]
fn flip_function() {
infer_eq(
indoc!(
r#"
\f -> (\a, b -> f b a)
"#
),
"(a, b -> c) -> (b, a -> c)",
);
}
#[test]
fn always_function() {
infer_eq(
indoc!(
r#"
\val -> \_ -> val
"#
),
"a -> (* -> a)",
);
}
#[test]
fn pass_a_function() {
infer_eq(
indoc!(
r#"
\f -> f {}
"#
),
"({} -> a) -> a",
);
}
#[test]
fn constrain_closure() {
infer_eq(