mirror of
https://github.com/roc-lang/roc.git
synced 2025-08-03 11:52:19 +00:00
Merge pull request #4887 from roc-lang/weakening-5
Finish weakening let-bindings
This commit is contained in:
commit
ed7123ed5b
11 changed files with 109 additions and 69 deletions
|
@ -3609,9 +3609,7 @@ pub fn rec_defs_help_simple(
|
|||
}
|
||||
_ => true, // this must be a function
|
||||
});
|
||||
// TODO(weakening)
|
||||
#[allow(clippy::logic_bug)]
|
||||
Generalizable(generalizable || true)
|
||||
Generalizable(generalizable)
|
||||
};
|
||||
|
||||
for index in range {
|
||||
|
@ -3861,11 +3859,11 @@ fn is_generalizable_expr(mut expr: &Expr) -> bool {
|
|||
| ExpectFx { .. }
|
||||
| Dbg { .. }
|
||||
| TypedHole(_)
|
||||
| RuntimeError(..) => return false,
|
||||
// TODO(weakening)
|
||||
Var(_, _) | AbilityMember(_, _, _) | Tag { .. } | ZeroArgumentTag { .. } => {
|
||||
return true
|
||||
}
|
||||
| RuntimeError(..)
|
||||
| ZeroArgumentTag { .. }
|
||||
| Tag { .. }
|
||||
| AbilityMember(..)
|
||||
| Var(..) => return false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3901,9 +3899,7 @@ fn rec_defs_help(
|
|||
let generalizable = defs
|
||||
.iter()
|
||||
.all(|d| is_generalizable_expr(&d.loc_expr.value));
|
||||
// TODO(weakening)
|
||||
#[allow(clippy::logic_bug)]
|
||||
Generalizable(generalizable || true)
|
||||
Generalizable(generalizable)
|
||||
};
|
||||
|
||||
for def in defs {
|
||||
|
|
|
@ -429,7 +429,7 @@ fn test_load_and_typecheck() {
|
|||
"constantNum" => "Num *",
|
||||
"divisionTest" => "F64",
|
||||
"divDep1ByDep2" => "Float a",
|
||||
"fromDep2" => "Float *",
|
||||
"fromDep2" => "Float a",
|
||||
},
|
||||
);
|
||||
}
|
||||
|
|
|
@ -943,12 +943,14 @@ mod solve_expr {
|
|||
infer_eq_without_problem(
|
||||
indoc!(
|
||||
r#"
|
||||
foo = Foo
|
||||
foo0 = Foo
|
||||
foo1 = Foo
|
||||
foo2 = Foo
|
||||
|
||||
{
|
||||
x: [foo, Foo],
|
||||
y: [foo, \x -> Foo x],
|
||||
z: [foo, \x,y -> Foo x y]
|
||||
x: [foo0, Foo],
|
||||
y: [foo1, \x -> Foo x],
|
||||
z: [foo2, \x,y -> Foo x y]
|
||||
}
|
||||
"#
|
||||
),
|
||||
|
@ -2555,10 +2557,10 @@ mod solve_expr {
|
|||
infer_eq(
|
||||
indoc!(
|
||||
r#"
|
||||
ok : Result I64 *
|
||||
ok : Result I64 _
|
||||
ok = Ok 5
|
||||
|
||||
err : Result * Str
|
||||
err : Result _ Str
|
||||
err = Err "blah"
|
||||
|
||||
if 1 > 0 then
|
||||
|
@ -3101,7 +3103,6 @@ mod solve_expr {
|
|||
|
||||
#[test]
|
||||
fn rigid_in_letrec_ignored() {
|
||||
// re-enable when we don't capture local things that don't need to be!
|
||||
infer_eq_without_problem(
|
||||
indoc!(
|
||||
r#"
|
||||
|
@ -3109,7 +3110,7 @@ mod solve_expr {
|
|||
|
||||
toEmpty : ConsList a -> ConsList a
|
||||
toEmpty = \_ ->
|
||||
result : ConsList a
|
||||
result : ConsList _ # TODO to enable using `a` we need scoped variables
|
||||
result = Nil
|
||||
|
||||
toEmpty result
|
||||
|
@ -3132,7 +3133,7 @@ mod solve_expr {
|
|||
|
||||
toEmpty : ConsList a -> ConsList a
|
||||
toEmpty = \_ ->
|
||||
result : ConsList a
|
||||
result : ConsList _ # TODO to enable using `a` we need scoped variables
|
||||
result = Nil
|
||||
|
||||
toEmpty result
|
||||
|
@ -4353,12 +4354,12 @@ mod solve_expr {
|
|||
RBTree k v : [Node NodeColor k v (RBTree k v) (RBTree k v), Empty]
|
||||
|
||||
# Create an empty dictionary.
|
||||
empty : RBTree k v
|
||||
empty =
|
||||
empty : {} -> RBTree k v
|
||||
empty = \{} ->
|
||||
Empty
|
||||
|
||||
foo : RBTree I64 I64
|
||||
foo = empty
|
||||
foo = empty {}
|
||||
|
||||
main : RBTree I64 I64
|
||||
main =
|
||||
|
@ -6598,6 +6599,42 @@ mod solve_expr {
|
|||
#^^{-1}
|
||||
|
||||
main =
|
||||
alias1 = \x -> id x
|
||||
# ^^
|
||||
alias2 = \x -> alias1 x
|
||||
# ^^^^^^
|
||||
|
||||
a : A
|
||||
a = alias2 (@A {})
|
||||
# ^^^^^^
|
||||
|
||||
a
|
||||
"#
|
||||
),
|
||||
@r###"
|
||||
A#id(4) : A -[[id(4)]]-> A
|
||||
Id#id(2) : a -[[] + a:id(2):1]-> a | a has Id
|
||||
alias1 : a -[[alias1(6)]]-> a | a has Id
|
||||
alias2 : A -[[alias2(7)]]-> A
|
||||
"###
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn resolve_lambda_set_weakened_ability_alias() {
|
||||
infer_queries!(
|
||||
indoc!(
|
||||
r#"
|
||||
app "test" provides [main] to "./platform"
|
||||
|
||||
Id has id : a -> a | a has Id
|
||||
|
||||
A := {} has [Id {id}]
|
||||
id = \@A {} -> @A {}
|
||||
#^^{-1}
|
||||
|
||||
main =
|
||||
# Both alias1, alias2 should get weakened
|
||||
alias1 = id
|
||||
# ^^
|
||||
alias2 = alias1
|
||||
|
@ -6612,8 +6649,8 @@ mod solve_expr {
|
|||
),
|
||||
@r###"
|
||||
A#id(4) : A -[[id(4)]]-> A
|
||||
Id#id(2) : a -[[] + a:id(2):1]-> a | a has Id
|
||||
alias1 : a -[[] + a:id(2):1]-> a | a has Id
|
||||
Id#id(2) : A -[[id(4)]]-> A
|
||||
alias1 : A -[[id(4)]]-> A
|
||||
alias2 : A -[[id(4)]]-> A
|
||||
"###
|
||||
)
|
||||
|
@ -6743,8 +6780,8 @@ mod solve_expr {
|
|||
#^^{-1}
|
||||
|
||||
main =
|
||||
alias = id
|
||||
# ^^
|
||||
alias = \x -> id x
|
||||
# ^^
|
||||
|
||||
a : A
|
||||
a = (alias (@A {})) {}
|
||||
|
@ -6756,7 +6793,7 @@ mod solve_expr {
|
|||
@r#"
|
||||
A#id(5) : {} -[[id(5)]]-> ({} -[[8]]-> {})
|
||||
Id#id(3) : a -[[] + a:id(3):1]-> ({} -[[] + a:id(3):2]-> a) | a has Id
|
||||
alias : {} -[[id(5)]]-> ({} -[[8]]-> {})
|
||||
alias : {} -[[alias(9)]]-> ({} -[[8]]-> {})
|
||||
"#
|
||||
print_only_under_alias: true
|
||||
)
|
||||
|
@ -6991,7 +7028,7 @@ mod solve_expr {
|
|||
"#
|
||||
),
|
||||
@r#"
|
||||
foo : [Named Str (List a)]* as a
|
||||
foo : [Named Str (List a)] as a
|
||||
Named name outerList : [Named Str (List a)] as a
|
||||
name : Str
|
||||
outerList : List ([Named Str (List a)] as a)
|
||||
|
|
|
@ -3507,9 +3507,9 @@ fn monomorphized_ints_aliased() {
|
|||
app "test" provides [main] to "./platform"
|
||||
|
||||
main =
|
||||
y = 100
|
||||
w1 = y
|
||||
w2 = y
|
||||
y = \{} -> 100
|
||||
w1 = \{} -> y {}
|
||||
w2 = \{} -> y {}
|
||||
|
||||
f1 : U8, U32 -> U8
|
||||
f1 = \_, _ -> 1
|
||||
|
@ -3517,7 +3517,7 @@ fn monomorphized_ints_aliased() {
|
|||
f2 : U32, U8 -> U8
|
||||
f2 = \_, _ -> 2
|
||||
|
||||
f1 w1 w2 + f2 w1 w2
|
||||
f1 (w1 {}) (w2 {}) + f2 (w1 {}) (w2 {})
|
||||
"#
|
||||
),
|
||||
3,
|
||||
|
|
|
@ -1255,8 +1255,8 @@ fn linked_list_is_singleton() {
|
|||
|
||||
ConsList a : [Cons a (ConsList a), Nil]
|
||||
|
||||
empty : ConsList a
|
||||
empty = Nil
|
||||
empty : {} -> ConsList a
|
||||
empty = \{} -> Nil
|
||||
|
||||
isSingleton : ConsList a -> Bool
|
||||
isSingleton = \list ->
|
||||
|
@ -1270,7 +1270,7 @@ fn linked_list_is_singleton() {
|
|||
main : Bool
|
||||
main =
|
||||
myList : ConsList I64
|
||||
myList = empty
|
||||
myList = empty {}
|
||||
|
||||
isSingleton myList
|
||||
"#
|
||||
|
@ -1290,8 +1290,8 @@ fn linked_list_is_empty_1() {
|
|||
|
||||
ConsList a : [Cons a (ConsList a), Nil]
|
||||
|
||||
empty : ConsList a
|
||||
empty = Nil
|
||||
empty : {} -> ConsList a
|
||||
empty = \{} -> Nil
|
||||
|
||||
isEmpty : ConsList a -> Bool
|
||||
isEmpty = \list ->
|
||||
|
@ -1304,8 +1304,8 @@ fn linked_list_is_empty_1() {
|
|||
|
||||
main : Bool
|
||||
main =
|
||||
myList : ConsList (Int *)
|
||||
myList = empty
|
||||
myList : ConsList U8
|
||||
myList = empty {}
|
||||
|
||||
isEmpty myList
|
||||
"#
|
||||
|
|
|
@ -1237,10 +1237,10 @@ fn monomorphized_tag() {
|
|||
assert_evals_to!(
|
||||
indoc!(
|
||||
r#"
|
||||
b = Bar
|
||||
b = \{} -> Bar
|
||||
f : [Foo, Bar], [Bar, Baz] -> U8
|
||||
f = \_, _ -> 18
|
||||
f b b
|
||||
f (b {}) (b {})
|
||||
"#
|
||||
),
|
||||
18,
|
||||
|
@ -1279,8 +1279,8 @@ fn monomorphized_tag_with_polymorphic_arg() {
|
|||
app "test" provides [main] to "./platform"
|
||||
|
||||
main =
|
||||
a = A
|
||||
wrap = Wrapped a
|
||||
a = \{} -> A
|
||||
wrap = \{} -> Wrapped (a {})
|
||||
|
||||
useWrap1 : [Wrapped [A], Other] -> U8
|
||||
useWrap1 =
|
||||
|
@ -1294,7 +1294,7 @@ fn monomorphized_tag_with_polymorphic_arg() {
|
|||
Wrapped A -> 5
|
||||
Wrapped B -> 7
|
||||
|
||||
useWrap1 wrap * useWrap2 wrap
|
||||
useWrap1 (wrap {}) * useWrap2 (wrap {})
|
||||
"#
|
||||
),
|
||||
10,
|
||||
|
@ -1313,8 +1313,8 @@ fn monomorphized_tag_with_polymorphic_arg_and_monomorphic_arg() {
|
|||
main =
|
||||
mono : U8
|
||||
mono = 15
|
||||
poly = A
|
||||
wrap = Wrapped poly mono
|
||||
poly = \{} -> A
|
||||
wrap = \{} -> Wrapped (poly {}) mono
|
||||
|
||||
useWrap1 : [Wrapped [A] U8, Other] -> U8
|
||||
useWrap1 =
|
||||
|
@ -1328,7 +1328,7 @@ fn monomorphized_tag_with_polymorphic_arg_and_monomorphic_arg() {
|
|||
Wrapped A n -> n
|
||||
Wrapped B _ -> 0
|
||||
|
||||
useWrap1 wrap * useWrap2 wrap
|
||||
useWrap1 (wrap {}) * useWrap2 (wrap {})
|
||||
"#
|
||||
),
|
||||
225,
|
||||
|
@ -1428,7 +1428,7 @@ fn issue_2445() {
|
|||
r#"
|
||||
app "test" provides [main] to "./platform"
|
||||
|
||||
none : [None, Update a]
|
||||
none : [None, Update _]
|
||||
none = None
|
||||
|
||||
press : [None, Update U8]
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
procedure Test.0 ():
|
||||
let Test.4 : [<rnu><null>, C List *self] = TagId(1) ;
|
||||
let Test.5 : [C List [<rnu><null>, C List *self], C U16, C ] = TagId(2) ;
|
||||
let Test.12 : {[<rnu><null>, C List *self], [C List [<rnu><null>, C List *self], C U16, C ]} = Struct {Test.4, Test.5};
|
||||
let Test.4 : [<rnw>C List *self, C U16, <null>] = TagId(2) ;
|
||||
inc Test.4;
|
||||
let Test.12 : {[<rnw>C List *self, C U16, <null>], [<rnw>C List *self, C U16, <null>]} = Struct {Test.4, Test.4};
|
||||
ret Test.12;
|
||||
|
|
|
@ -1,8 +1,15 @@
|
|||
procedure Test.2 (Test.4, Test.5):
|
||||
let Test.7 : U8 = 18i64;
|
||||
ret Test.7;
|
||||
procedure Test.1 (Test.4):
|
||||
let Test.12 : Int1 = false;
|
||||
ret Test.12;
|
||||
|
||||
procedure Test.2 (Test.5, Test.6):
|
||||
let Test.10 : U8 = 18i64;
|
||||
ret Test.10;
|
||||
|
||||
procedure Test.0 ():
|
||||
let Test.1 : Int1 = false;
|
||||
let Test.6 : U8 = CallByName Test.2 Test.1 Test.1;
|
||||
ret Test.6;
|
||||
let Test.13 : {} = Struct {};
|
||||
let Test.8 : Int1 = CallByName Test.1 Test.13;
|
||||
let Test.11 : {} = Struct {};
|
||||
let Test.9 : Int1 = CallByName Test.1 Test.11;
|
||||
let Test.7 : U8 = CallByName Test.2 Test.8 Test.9;
|
||||
ret Test.7;
|
||||
|
|
|
@ -15,11 +15,11 @@ procedure Test.1 (Test.24, Test.25, Test.26):
|
|||
let Test.14 : Int1 = CallByName Num.22 Test.3 Test.4;
|
||||
if Test.14 then
|
||||
dec Test.2;
|
||||
let Test.23 : List [] = Array [];
|
||||
let Test.23 : List I64 = Array [];
|
||||
let Test.22 : I64 = 0i64;
|
||||
let Test.21 : {I64, List []} = Struct {Test.22, Test.23};
|
||||
let Test.21 : {I64, List I64} = Struct {Test.22, Test.23};
|
||||
let Test.5 : I64 = StructAtIndex 0 Test.21;
|
||||
let Test.6 : List [] = StructAtIndex 1 Test.21;
|
||||
let Test.6 : List I64 = StructAtIndex 1 Test.21;
|
||||
inc Test.6;
|
||||
dec Test.21;
|
||||
let Test.20 : I64 = 1i64;
|
||||
|
|
|
@ -1199,10 +1199,10 @@ fn monomorphized_tag() {
|
|||
app "test" provides [main] to "./platform"
|
||||
|
||||
main =
|
||||
b = Bar
|
||||
b = \{} -> Bar
|
||||
f : [Foo, Bar], [Bar, Baz] -> U8
|
||||
f = \_, _ -> 18
|
||||
f b b
|
||||
f (b {}) (b {})
|
||||
"#
|
||||
)
|
||||
}
|
||||
|
@ -1800,7 +1800,7 @@ fn instantiate_annotated_as_recursive_alias_toplevel() {
|
|||
|
||||
Value : [Nil, Array (List Value)]
|
||||
|
||||
foo : [Nil]*
|
||||
foo : [Nil]_
|
||||
foo = Nil
|
||||
|
||||
it : Value
|
||||
|
@ -1818,7 +1818,7 @@ fn instantiate_annotated_as_recursive_alias_polymorphic_expr() {
|
|||
main =
|
||||
Value : [Nil, Array (List Value)]
|
||||
|
||||
foo : [Nil]*
|
||||
foo : [Nil]_
|
||||
foo = Nil
|
||||
|
||||
it : Value
|
||||
|
@ -1838,7 +1838,7 @@ fn instantiate_annotated_as_recursive_alias_multiple_polymorphic_expr() {
|
|||
main =
|
||||
Value : [Nil, Array (List Value)]
|
||||
|
||||
foo : [Nil]*
|
||||
foo : [Nil]_
|
||||
foo = Nil
|
||||
|
||||
v1 : Value
|
||||
|
|
|
@ -666,10 +666,10 @@ mod test {
|
|||
|
||||
When it failed, these variables had these values:
|
||||
|
||||
a : [Ok Str]
|
||||
a : [Err Str, Ok Str]
|
||||
a = Ok "Astra mortemque praestare gradatim"
|
||||
|
||||
b : [Err Str]
|
||||
b : [Err Str, Ok Str]
|
||||
b = Err "Profundum et fundamentum"
|
||||
"#
|
||||
),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue