Merge remote-tracking branch 'origin/trunk' into low-level-ops

This commit is contained in:
Richard Feldman 2020-07-07 21:02:03 -04:00
commit 1cd49689c2
29 changed files with 1630 additions and 440 deletions

View file

@ -1017,7 +1017,7 @@ mod solve_uniq_expr {
.left
"#
),
"Attr * (Attr (* | a) { left : (Attr a b) }* -> Attr a b)",
"Attr * (Attr (* | b) { left : (Attr b a) }* -> Attr b a)",
);
}
@ -1029,7 +1029,7 @@ mod solve_uniq_expr {
\rec -> rec.left
"#
),
"Attr * (Attr (* | a) { left : (Attr a b) }* -> Attr a b)",
"Attr * (Attr (* | b) { left : (Attr b a) }* -> Attr b a)",
);
}
@ -1041,7 +1041,7 @@ mod solve_uniq_expr {
\{ left, right } -> { left, right }
"#
),
"Attr * (Attr (* | a | b) { left : (Attr a c), right : (Attr b d) }* -> Attr * { left : (Attr a c), right : (Attr b d) })"
"Attr * (Attr (* | b | d) { left : (Attr b a), right : (Attr d c) }* -> Attr * { left : (Attr b a), right : (Attr d c) })"
);
}
@ -1068,7 +1068,7 @@ mod solve_uniq_expr {
),
// NOTE: Foo loses the relation to the uniqueness attribute `a`
// That is fine. Whenever we try to extract from it, the relation will be enforced
"Attr * (Attr (* | a) [ Foo (Attr a b) ]* -> Attr * [ Foo (Attr a b) ]*)",
"Attr * (Attr (* | b) [ Foo (Attr b a) ]* -> Attr * [ Foo (Attr b a) ]*)",
);
}
@ -1083,8 +1083,7 @@ mod solve_uniq_expr {
// TODO: is it safe to ignore uniqueness constraints from patterns that bind no identifiers?
// i.e. the `b` could be ignored in this example, is that true in general?
// seems like it because we don't really extract anything.
// "Attr * (Attr (* | a | b) [ Foo (Attr b c) (Attr a *) ]* -> Attr * [ Foo (Attr b c) (Attr * Str) ]*)"
"Attr * (Attr (* | a | b) [ Foo (Attr a c) (Attr b *) ]* -> Attr * [ Foo (Attr a c) (Attr * Str) ]*)"
"Attr * (Attr (* | b | c) [ Foo (Attr b a) (Attr c *) ]* -> Attr * [ Foo (Attr b a) (Attr * Str) ]*)"
);
}
@ -1137,7 +1136,7 @@ mod solve_uniq_expr {
\{ left } -> left
"#
),
"Attr * (Attr (* | a) { left : (Attr a b) }* -> Attr a b)",
"Attr * (Attr (* | b) { left : (Attr b a) }* -> Attr b a)",
);
}
@ -1149,7 +1148,7 @@ mod solve_uniq_expr {
\{ left } -> left
"#
),
"Attr * (Attr (* | a) { left : (Attr a b) }* -> Attr a b)",
"Attr * (Attr (* | b) { left : (Attr b a) }* -> Attr b a)",
);
}
@ -1164,7 +1163,7 @@ mod solve_uniq_expr {
numIdentity
"#
),
"Attr * (Attr a (Num (Attr b p)) -> Attr a (Num (Attr b p)))",
"Attr * (Attr b (Num (Attr a p)) -> Attr b (Num (Attr a p)))",
);
}
@ -1179,7 +1178,7 @@ mod solve_uniq_expr {
x
"#
),
"Attr * (Attr (* | a) { left : (Attr a b) }* -> Attr a b)",
"Attr * (Attr (* | b) { left : (Attr b a) }* -> Attr b a)",
);
}
@ -1194,7 +1193,7 @@ mod solve_uniq_expr {
x
"#
),
"Attr * (Attr (* | a) { left : (Attr a b) }* -> Attr a b)",
"Attr * (Attr (* | b) { left : (Attr b a) }* -> Attr b a)",
);
}
@ -1212,7 +1211,7 @@ mod solve_uniq_expr {
{ numIdentity, p, q }
"#
),
"Attr * { numIdentity : (Attr Shared (Attr a (Num (Attr b p)) -> Attr a (Num (Attr b p)))), p : (Attr * (Num (Attr * p))), q : (Attr * Float) }"
"Attr * { numIdentity : (Attr Shared (Attr b (Num (Attr a p)) -> Attr b (Num (Attr a p)))), p : (Attr * (Num (Attr * p))), q : (Attr * Float) }"
);
}
@ -1228,7 +1227,7 @@ mod solve_uniq_expr {
r
"#
),
"Attr * (Attr a { x : (Attr Shared b) }c -> Attr a { x : (Attr Shared b) }c)",
"Attr * (Attr c { x : (Attr Shared a) }b -> Attr c { x : (Attr Shared a) }b)",
);
}
@ -1244,7 +1243,7 @@ mod solve_uniq_expr {
r
"#
),
"Attr * (Attr a { x : (Attr Shared b), y : (Attr Shared c) }d -> Attr a { x : (Attr Shared b), y : (Attr Shared c) }d)",
"Attr * (Attr d { x : (Attr Shared a), y : (Attr Shared b) }c -> Attr d { x : (Attr Shared a), y : (Attr Shared b) }c)",
);
}
@ -1263,7 +1262,7 @@ mod solve_uniq_expr {
p)
"#
),
"Attr * (Attr a { x : (Attr Shared b), y : (Attr Shared c) }d -> Attr a { x : (Attr Shared b), y : (Attr Shared c) }d)"
"Attr * (Attr d { x : (Attr Shared a), y : (Attr Shared b) }c -> Attr d { x : (Attr Shared a), y : (Attr Shared b) }c)"
);
}
@ -1279,7 +1278,7 @@ mod solve_uniq_expr {
r
"#
),
"Attr * (Attr a { x : (Attr Shared b) }c -> Attr a { x : (Attr Shared b) }c)",
"Attr * (Attr c { x : (Attr Shared a) }b -> Attr c { x : (Attr Shared a) }b)",
);
}
@ -1291,7 +1290,7 @@ mod solve_uniq_expr {
\r -> { r & x: r.x, y: r.x }
"#
),
"Attr * (Attr a { x : (Attr Shared b), y : (Attr Shared b) }c -> Attr a { x : (Attr Shared b), y : (Attr Shared b) }c)"
"Attr * (Attr c { x : (Attr Shared a), y : (Attr Shared a) }b -> Attr c { x : (Attr Shared a), y : (Attr Shared a) }b)"
);
}
@ -1307,7 +1306,7 @@ mod solve_uniq_expr {
r
"#
),
"Attr * (Attr (a | b) { foo : (Attr b { bar : (Attr Shared d), baz : (Attr Shared c) }e) }f -> Attr (a | b) { foo : (Attr b { bar : (Attr Shared d), baz : (Attr Shared c) }e) }f)"
"Attr * (Attr (f | d) { foo : (Attr d { bar : (Attr Shared a), baz : (Attr Shared b) }c) }e -> Attr (f | d) { foo : (Attr d { bar : (Attr Shared a), baz : (Attr Shared b) }c) }e)"
);
}
@ -1325,7 +1324,7 @@ mod solve_uniq_expr {
r
"#
),
"Attr * (Attr (a | b) { foo : (Attr b { bar : (Attr Shared c) }d) }e -> Attr (a | b) { foo : (Attr b { bar : (Attr Shared c) }d) }e)"
"Attr * (Attr (e | c) { foo : (Attr c { bar : (Attr Shared a) }b) }d -> Attr (e | c) { foo : (Attr c { bar : (Attr Shared a) }b) }d)"
);
}
@ -1344,7 +1343,7 @@ mod solve_uniq_expr {
s
"#
),
"Attr * (Attr a { x : (Attr Shared b), y : (Attr Shared b) }c -> Attr a { x : (Attr Shared b), y : (Attr Shared b) }c)",
"Attr * (Attr c { x : (Attr Shared a), y : (Attr Shared a) }b -> Attr c { x : (Attr Shared a), y : (Attr Shared a) }b)",
);
}
@ -1360,8 +1359,7 @@ mod solve_uniq_expr {
r.tic.tac.toe
"#
),
// "Attr * (Attr (* | a | b | c | d | e) { foo : (Attr (d | b | e) { bar : (Attr (e | b) { baz : (Attr b f) }*) }*), tic : (Attr (a | b | c) { tac : (Attr (c | b) { toe : (Attr b f) }*) }*) }* -> Attr b f)"
"Attr * (Attr (* | a | b | c | d | e) { foo : (Attr (a | b | d) { bar : (Attr (d | b) { baz : (Attr b f) }*) }*), tic : (Attr (c | b | e) { tac : (Attr (e | b) { toe : (Attr b f) }*) }*) }* -> Attr b f)"
"Attr * (Attr (* | b | c | d | e | f) { foo : (Attr (d | b | c) { bar : (Attr (c | b) { baz : (Attr b a) }*) }*), tic : (Attr (f | b | e) { tac : (Attr (e | b) { toe : (Attr b a) }*) }*) }* -> Attr b a)"
);
}
@ -1694,7 +1692,7 @@ mod solve_uniq_expr {
map
"#
),
"Attr Shared (Attr Shared (Attr a b -> c), Attr (d | a) [ Cons (Attr a b) (Attr (d | a) e), Nil ]* as e -> Attr f [ Cons c (Attr f g), Nil ]* as g)" ,
"Attr Shared (Attr Shared (Attr b a -> c), Attr (e | b) [ Cons (Attr b a) (Attr (e | b) d), Nil ]* as d -> Attr g [ Cons c (Attr g f), Nil ]* as f)" ,
);
}
@ -1735,7 +1733,7 @@ mod solve_uniq_expr {
map
"#
),
"Attr Shared (Attr a [ S (Attr a b), Z ]* as b -> Attr c [ S (Attr c d), Z ]* as d)",
"Attr Shared (Attr b [ S (Attr b a), Z ]* as a -> Attr d [ S (Attr d c), Z ]* as c)",
);
}
@ -1874,30 +1872,76 @@ mod solve_uniq_expr {
);
}
// #[test]
// fn assoc_list_map() {
// infer_eq(
// indoc!(
// r#"
// ConsList a : [ Cons a (ConsList a), Nil ]
// AssocList a b : ConsList { key: a, value : b }
//
// map : AssocList k v -> AssocList k v
// map = \list ->
// when list is
// Cons { key, value } xs ->
// Cons {key: key, value: value } xs
//
// Nil ->
// Nil
//
// map
// "#
// ),
// // "Attr Shared (Attr Shared (Attr Shared k, Attr a v -> Attr b v2), Attr (c | d | e) (AssocList (Attr Shared k) (Attr a v)) -> Attr (c | d | e) (AssocList (Attr Shared k) (Attr b v2)))"
// "Attr Shared (Attr Shared (Attr a p -> Attr b q), Attr (* | a) (ConsList (Attr a p)) -> Attr * (ConsList (Attr b q)))",
// );
// }
#[test]
fn alias_assoc_list_head() {
infer_eq(
indoc!(
r#"
ConsList a : [ Cons a (ConsList a), Nil ]
AssocList a b : ConsList { key: a, value : b }
Maybe a : [ Just a, Nothing ]
# AssocList2 a b : [ Cons { key: a, value : b } (AssocList2 a b), Nil ]
head : AssocList k v -> Maybe { key: k , value: v }
head = \alist ->
when alist is
Cons first _ ->
Just first
Nil ->
Nothing
head
"#
),
"Attr * (Attr (* | c) (AssocList (Attr a k) (Attr b v)) -> Attr * (Maybe (Attr c { key : (Attr a k), value : (Attr b v) })))"
);
}
#[test]
fn cons_list_as_assoc_list_head() {
infer_eq(
indoc!(
r#"
ConsList a : [ Cons a (ConsList a), Nil ]
Maybe a : [ Just a, Nothing ]
head : ConsList { key: k, value: v } -> Maybe { key: k , value: v }
head = \alist ->
when alist is
Cons first _ ->
Just first
Nil ->
Nothing
head
"#
),
"Attr * (Attr (* | c) (ConsList (Attr c { key : (Attr a k), value : (Attr b v) })) -> Attr * (Maybe (Attr c { key : (Attr a k), value : (Attr b v) })))"
);
}
#[test]
fn assoc_list_map() {
infer_eq(
indoc!(
r#"
ConsList a : [ Cons a (ConsList a), Nil ]
map : ConsList a -> ConsList a
map = \list ->
when list is
Cons r xs -> Cons r xs
Nil -> Nil
map
"#
),
"Attr * (Attr (c | b) (ConsList (Attr b a)) -> Attr (c | b) (ConsList (Attr b a)))",
);
}
#[test]
fn same_uniqueness_builtin_list() {
@ -1965,6 +2009,40 @@ mod solve_uniq_expr {
);
}
#[test]
fn typecheck_triple_mutually_recursive_tag_union() {
infer_eq(
indoc!(
r#"
ListA a b : [ Cons a (ListB b a), Nil ]
ListB a b : [ Cons a (ListC b a), Nil ]
ListC a b : [ Cons a (ListA b a), Nil ]
ConsList q : [ Cons q (ConsList q), Nil ]
toAs : (q -> p), ListA p q -> ConsList p
toAs =
\f, lista ->
when lista is
Nil -> Nil
Cons a listb ->
when listb is
Nil -> Nil
Cons b listc ->
when listc is
Nil ->
Nil
Cons c newListA ->
Cons a (Cons (f b) (Cons c (toAs f newListA)))
toAs
"#
),
"Attr Shared (Attr Shared (Attr a q -> Attr b p), Attr (* | a | b) (ListA (Attr b p) (Attr a q)) -> Attr * (ConsList (Attr b p)))"
);
}
#[test]
fn infer_mutually_recursive_tag_union() {
infer_eq(
@ -1982,7 +2060,7 @@ mod solve_uniq_expr {
toAs
"#
),
"Attr Shared (Attr Shared (Attr a b -> c), Attr (d | a | e) [ Cons (Attr e f) (Attr (d | a | e) [ Cons (Attr a b) (Attr (d | a | e) g), Nil ]*), Nil ]* as g -> Attr h [ Cons (Attr e f) (Attr * [ Cons c (Attr h i) ]*), Nil ]* as i)"
"Attr Shared (Attr Shared (Attr b a -> c), Attr (g | b | e) [ Cons (Attr e d) (Attr (g | b | e) [ Cons (Attr b a) (Attr (g | b | e) f), Nil ]*), Nil ]* as f -> Attr i [ Cons (Attr e d) (Attr * [ Cons c (Attr i h) ]*), Nil ]* as h)"
);
}
@ -2016,10 +2094,10 @@ mod solve_uniq_expr {
infer_eq(
indoc!(
r#"
Num.maxFloat / Num.maxFloat
"#
Num.maxFloat / Num.maxFloat
"#
),
"Attr * Float",
"Attr * (Result (Attr * Float) (Attr * [ DivByZero ]*))",
);
}
@ -2028,10 +2106,10 @@ mod solve_uniq_expr {
infer_eq(
indoc!(
r#"
3.0 / 4.0
"#
3.0 / 4.0
"#
),
"Attr * Float",
"Attr * (Result (Attr * Float) (Attr * [ DivByZero ]*))",
);
}
@ -2040,10 +2118,10 @@ mod solve_uniq_expr {
infer_eq(
indoc!(
r#"
3.0 / Num.maxFloat
"#
3.0 / Num.maxFloat
"#
),
"Attr * Float",
"Attr * (Result (Attr * Float) (Attr * [ DivByZero ]*))",
);
}
@ -2052,8 +2130,8 @@ mod solve_uniq_expr {
infer_eq(
indoc!(
r#"
Num.maxInt // Num.maxInt
"#
Num.maxInt // Num.maxInt
"#
),
"Attr * (Result (Attr * Int) (Attr * [ DivByZero ]*))",
);
@ -2064,8 +2142,8 @@ mod solve_uniq_expr {
infer_eq(
indoc!(
r#"
3 // 4
"#
3 // 4
"#
),
"Attr * (Result (Attr * Int) (Attr * [ DivByZero ]*))",
);
@ -2076,8 +2154,8 @@ mod solve_uniq_expr {
infer_eq(
indoc!(
r#"
3 // Num.maxInt
"#
3 // Num.maxInt
"#
),
"Attr * (Result (Attr * Int) (Attr * [ DivByZero ]*))",
);
@ -2088,12 +2166,12 @@ mod solve_uniq_expr {
infer_eq(
indoc!(
r#"
\list ->
p = List.get list 1
q = List.get list 1
\list ->
p = List.get list 1
q = List.get list 1
{ p, q }
"#
{ p, q }
"#
),
"Attr * (Attr * (List (Attr Shared a)) -> Attr * { p : (Attr * (Result (Attr Shared a) (Attr * [ OutOfBounds ]*))), q : (Attr * (Result (Attr Shared a) (Attr * [ OutOfBounds ]*))) })"
);
@ -2113,7 +2191,7 @@ mod solve_uniq_expr {
list
"#
),
"Attr * (Attr a (List (Attr Shared (Num (Attr Shared b)))) -> Attr a (List (Attr Shared (Num (Attr Shared b)))))",
"Attr * (Attr b (List (Attr Shared (Num (Attr Shared a)))) -> Attr b (List (Attr Shared (Num (Attr Shared a)))))",
);
}
@ -2129,7 +2207,7 @@ mod solve_uniq_expr {
List.set list 0 42
"#
),
"Attr * (Attr (a | b) (List (Attr b (Num (Attr c d)))) -> Attr (a | b) (List (Attr b (Num (Attr c d)))))",
"Attr * (Attr (d | c) (List (Attr c (Num (Attr b a)))) -> Attr (d | c) (List (Attr c (Num (Attr b a)))))",
);
}
@ -2151,7 +2229,7 @@ mod solve_uniq_expr {
sum
"#
),
"Attr * (Attr (* | a) (List (Attr a (Num (Attr a b)))) -> Attr c (Num (Attr c b)))",
"Attr * (Attr (* | b) (List (Attr b (Num (Attr b a)))) -> Attr c (Num (Attr c a)))",
);
}
@ -2159,7 +2237,7 @@ mod solve_uniq_expr {
fn num_add() {
infer_eq(
"Num.add",
"Attr * (Attr a (Num (Attr a b)), Attr c (Num (Attr c b)) -> Attr d (Num (Attr d b)))",
"Attr * (Attr b (Num (Attr b a)), Attr c (Num (Attr c a)) -> Attr d (Num (Attr d a)))",
);
}
@ -2175,12 +2253,12 @@ mod solve_uniq_expr {
#[test]
fn list_get() {
infer_eq("List.get", "Attr * (Attr (* | a) (List (Attr a b)), Attr * Int -> Attr * (Result (Attr a b) (Attr * [ OutOfBounds ]*)))");
infer_eq("List.get", "Attr * (Attr (* | b) (List (Attr b a)), Attr * Int -> Attr * (Result (Attr b a) (Attr * [ OutOfBounds ]*)))");
}
#[test]
fn list_set() {
infer_eq("List.set", "Attr * (Attr (* | a | b) (List (Attr a c)), Attr * Int, Attr (a | b) c -> Attr * (List (Attr a c)))");
infer_eq("List.set", "Attr * (Attr (* | b | c) (List (Attr b a)), Attr * Int, Attr (b | c) a -> Attr * (List (Attr b a)))");
}
#[test]
@ -2216,7 +2294,7 @@ mod solve_uniq_expr {
fn list_foldr() {
infer_eq(
"List.foldr",
"Attr * (Attr (* | a) (List (Attr a b)), Attr Shared (Attr a b, c -> c), c -> c)",
"Attr * (Attr (* | b) (List (Attr b a)), Attr Shared (Attr b a, c -> c), c -> c)",
);
}
@ -2240,10 +2318,11 @@ mod solve_uniq_expr {
indoc!(
r#"
reverse = \list -> List.foldr list (\e, l -> List.push l e) []
reverse
"#
),
"Attr * (Attr (* | a) (List (Attr a b)) -> Attr * (List (Attr a b)))",
"Attr * (Attr (* | b) (List (Attr b a)) -> Attr * (List (Attr b a)))",
);
}
@ -2291,7 +2370,7 @@ mod solve_uniq_expr {
fn set_foldl() {
infer_eq(
"Set.foldl",
"Attr * (Attr (* | a) (Set (Attr a b)), Attr Shared (Attr a b, c -> c), c -> c)",
"Attr * (Attr (* | b) (Set (Attr b a)), Attr Shared (Attr b a, c -> c), c -> c)",
);
}
@ -2304,7 +2383,7 @@ mod solve_uniq_expr {
fn set_remove() {
infer_eq(
"Set.remove",
"Attr * (Attr * (Set (Attr a b)), Attr * b -> Attr * (Set (Attr a b)))",
"Attr * (Attr * (Set (Attr b a)), Attr * a -> Attr * (Set (Attr b a)))",
);
}
@ -2320,7 +2399,7 @@ mod solve_uniq_expr {
#[test]
fn map_get() {
infer_eq("Map.get", "Attr * (Attr (* | a) (Map (Attr * b) (Attr a c)), Attr * b -> Attr * (Result (Attr a c) (Attr * [ KeyNotFound ]*)))");
infer_eq("Map.get", "Attr * (Attr (* | c) (Map (Attr * a) (Attr c b)), Attr * a -> Attr * (Result (Attr c b) (Attr * [ KeyNotFound ]*)))");
}
#[test]
@ -2498,8 +2577,7 @@ mod solve_uniq_expr {
withDefault
"#
),
// "Attr * (Attr (* | b | c) (Result (Attr b a) (Attr c e)), Attr b a -> Attr b a)",
"Attr * (Attr (* | b | c) (Result (Attr c a) (Attr b e)), Attr c a -> Attr c a)",
"Attr * (Attr (* | b | c) (Result (Attr b a) (Attr c e)), Attr b a -> Attr b a)",
);
}
@ -2514,8 +2592,7 @@ mod solve_uniq_expr {
Err _ -> default
"#
),
// "Attr * (Attr (* | a | b) [ Err (Attr a *), Ok (Attr b c) ]*, Attr b c -> Attr b c)",
"Attr * (Attr (* | a | b) [ Err (Attr b *), Ok (Attr a c) ]*, Attr a c -> Attr a c)",
"Attr * (Attr (* | a | c) [ Err (Attr a *), Ok (Attr c b) ]*, Attr c b -> Attr c b)",
);
}
@ -2603,7 +2680,7 @@ mod solve_uniq_expr {
f
"#
),
"Attr * (Attr a (Num (Attr a b)), Attr c (Num (Attr c b)) -> Attr d (Num (Attr d b)))",
"Attr * (Attr b (Num (Attr b a)), Attr c (Num (Attr c a)) -> Attr d (Num (Attr d a)))",
);
}
@ -2630,7 +2707,7 @@ mod solve_uniq_expr {
\x -> Num.abs x
"#
),
"Attr * (Attr a (Num (Attr a b)) -> Attr c (Num (Attr c b)))",
"Attr * (Attr b (Num (Attr b a)) -> Attr c (Num (Attr c a)))",
);
}
@ -2648,8 +2725,8 @@ mod solve_uniq_expr {
f
"#
),
"Attr * (Attr (* | a | b) { p : (Attr a *), q : (Attr b *) }* -> Attr * (Num (Attr * *)))",
// "Attr * (Attr (* | a | b) { p : (Attr b *), q : (Attr a *) }* -> Attr * (Num (Attr * *)))"
//"Attr * (Attr (* | a | b) { p : (Attr a *), q : (Attr b *) }* -> Attr * (Num (Attr * *)))",
"Attr * (Attr (* | a | b) { p : (Attr a *), q : (Attr b *) }* -> Attr * (Num (Attr * *)))"
);
}