Commit graph

143 commits

Author SHA1 Message Date
Folkert
d8fa2b8d92
stop passing stdlib (use lazy_static) 2022-03-22 19:53:02 +01:00
ayazhafiz
5670fe06cd Deal with destructuring tag unions behind opaques correctly
Closes #2702
2022-03-13 18:44:38 -05:00
Folkert
e3e9215578
Merge remote-tracking branch 'origin/trunk' into type-checking-storage-subs 2022-03-12 14:10:43 +01:00
Folkert
01b810266b
test cleanup 2022-03-11 22:15:36 +01:00
Brendan Hansknecht
d681062c63 add Num.toNat 2022-03-11 11:17:42 -08:00
ayazhafiz
47e4904075 Chase aliases when checking for valid extension types 2022-03-06 22:17:58 -05:00
ayazhafiz
3bff99b0a2 Register accessor closures when they are bound
Previously we only registered record accessor closures in anonymous
contexts, where we assume they must already be specialized based on the
surrounding contexts. This is not true in general since one might bind
an accessor to a name.

Closes #2567
2022-03-06 10:53:12 -05:00
Folkert
80956061dd
fix formatting bug in type pretty-print 2022-03-05 15:03:59 +01:00
Folkert
6370a80c62
make sure lambda sets within aliases are in IntroducedVariables 2022-03-05 14:29:34 +01:00
Folkert
241dc5783e
remove VariablesIter, it was unused 2022-03-05 01:37:23 +01:00
Folkert
db06c10b5f
be smarter 2022-03-04 23:02:10 +01:00
ayazhafiz
b6d7229525 Infer + checking tests for opaques 2022-02-27 00:10:12 -05:00
ayazhafiz
d90915a8cd Implement Num.to* builtins
Just wrap over Num.intCast
2022-02-19 11:28:41 -05:00
ayazhafiz
909fae5b6c Generalize recursion variables properly
Closes #2379
Closes #2481
2022-02-18 00:07:38 -05:00
Folkert
04adbe75ca fix test compilation 2022-02-14 21:09:51 +01:00
ayazhafiz
8c0e39211d Instantiate recursive aliases to their smallest closures
Now, when we have two aliases like

```
T a : [ A, B (U a) ]
U a : [ C, D (T a) ]
```

during the first pass, we simply canonicalize them but add neither to
the scope. This means that `T` will not be instantiated in the
definition of `U`. Only in the second pass, during correction, do we
instantiate both aliases **independently**:

```
T a : [ A, B [ C, D (T a) ] ]
U a : [ C, D [ A, B (U a) ] ]
```

and now we can mark each recursive, individually:

```
T a : [ A, B [ C, D <rec1> ] ] as <rec1>
U a : [ C, D [ A, B <rec2> ] ] as <rec2>
```

This means that the surface types shown to users might be a bit larger,
but it has the benefit that everything needed to understand a layout of
a type in later passes is stored on the type directly, and we don't need
to keep alias mappings.

Since we sort by connected components, this should be complete.

Closes #2458
2022-02-11 08:43:33 -05:00
ayazhafiz
df8113ce32 Typecheck numeric suffixes in patterns 2022-02-01 23:35:14 -05:00
ayazhafiz
e03592930f Typecheck numeric literals with suffixes in expressions
Part of #2350
2022-02-01 22:49:50 -05:00
Folkert
b9c318e9fb update the tests 2022-01-26 15:59:21 +01:00
Jan Van Bruggen
591477e77b Add most remaining Num.min/max* builtins
This skips `min/maxU128`, as they require a subtle change
to the `I128`-centric implementation of `Int`s.
2022-01-17 15:26:23 -07:00
Jan Van Bruggen
d7e2be306f WIP: Add Num.minI128 builtin (TODOs remain) 2022-01-15 17:49:15 -07:00
Joshua Warner
a3c6bfce43 Mark infer_union_def_position as a test (followup to #2305) 2022-01-03 20:11:06 -08:00
ayazhafiz
8e7ca57458 Close tag unions that are in the left hand side of an assignment 2021-12-30 19:51:14 -06:00
ayazhafiz
fda6c70835 Mark patterns in lambda argument position as having a presence constraint
Closes #2299
2021-12-30 18:21:28 -06:00
ayazhafiz
b3ddfa7515 Parse destructured tag annotations as annotations rather than aliases
Closes #178
2021-12-26 16:11:29 -06:00
ayazhafiz
b97ff380e3 Presence constraints for tag union types
This work is related to restricting tag union sizes in input positions.
As an example, for something like

```
\x -> when x is
    A M -> X
    A N -> X
    A _ -> X
```

we'd like to infer `[A [M, N]* ]` rather than the `[A, [M, N]* ]*` we
infer today. Notice the difference is that the former type tells us we
only accepts `A`s, but the argument of the `A` can be `M`, `N` or
anything else (hence the `_`).

So what's the idea? It's an encoding of the "must have"/"might have"
design discussed in https://github.com/rtfeldman/roc/issues/1758. Let's
take our example above and walk through unification of each branch.

Suppose `x` starts off as a flex var `t`.

```
\x -> when x is
    A M -> X
```

Now we introduce a new kind of constraint called a "presence"
constraint. It says "t has at least [A [M]]". I'll notate this as `t +=
[A [M]]`. When `t` is free as it is here, this is equivalent to `t ~
[A [M]]`.

```
\x -> when x is
    ...
    A N -> X
```

At this branch we introduce the presence constraint `[A [M]] += [A [N]]`.
Notice that there's two tag unions we care about resolving here - one is
the toplevel one that says "I have an `A ...` inside of me", and the
other one is the tag union that's the tyarg to `A`. They are distinct
and at different depths.

For the toplevel one, we first figure out if the number of tags in the
union needs to expand. It does not - we're hoping to resolve the type
`[A [M, N]]`, which only has `A` in the toplevel union. So, we don't
need to do anything extra there, other than the merge the nested tag
unions.

We recurse on the shared tags, and now we have the presence constraint
`[M] += [N]`. At this point it's important to remember that the left and
right hand types are backed by type variables, so this is really
something like `t11 [M] += t12 [N]`, where `[M]` and `[N]` are just what
we know the variables `t11` and `t12` to be at this moment. So how do we
solve for `t11 [M, N]` from here? Well, we can encode this constraint as
a type variable definition and a unification constraint we already know
how to solve:

```
New definition: t11 [M]a    (a fresh)
New constraint: a ~ t12 [N]
```

That's it; upon unification, `t11 [M, N]` falls out.

Okay, last step.

```
\x -> when x is
    ...
    A _ -> X
```

We now have `[A [M, N]] += [A a]`, where `a` is a fresh unbound
variable. Again nothing has to happen on the toplevel. We walk down and
find `t11 [M, N] += t21 a`. This is actually called an "open constraint"; we
differentiate it at the time we generate constraints because it follows
syntactically from the presence of an `_`, but it's semantically
equivalent to the presence constraint `t11 [M, N] += t21 a`. It's just
called opening because literally the only way `t11 [M, N] += t21 a` can
be true is if we set `t11 a`. Well, actually, we assume `a` is a tag
union, so we just make `t11` the open tag union `[M, N]a`. Since `a` is
unbound, this eventually becomes a wildcard and hence falls out `[M, N]*`.
Also, once we open a tag union with an open constraint, we never close
it again.

That's it. The rest falls out recursively. This gives us a really easy
way to encode these ordering constraints in the unification-based system
we have today with minimal additional intervention. We do have to patch
variables in-place sometimes, and the additive nature of these
constraints feels about out-of-place relative to unification, but it
seems to work well.

Resolves #1758
2021-12-23 19:40:18 -06:00
ayazhafiz
88888b0854 Mark tag unions to recursive when they become so during unification
See the comment on line 811 of unify.rs in this commit for motivation
and justification.

Closes #2217
2021-12-22 17:51:07 -06:00
Folkert
c6b06005cc mut not needed 2021-12-05 15:40:11 +01:00
Folkert
4af9539ce6 fixes by cargo clippy --fix 2021-12-05 15:04:28 +01:00
rvcas
40090f20e6 test: update tests to use Num.toStr 2021-11-30 14:56:08 -05:00
ayazhafiz
1135d88dd0 Add support for type inference at _s in type definitions
All we have to do is introduce a new, unconstrained type variable at
underscore sites, and let the type reconstructor work its magic! The
unconstrained type variable will become a `FlexVar` that absorbs
constraints given to it, so it'll behave like a proper inference
variable. That's it!

Part of #1804
2021-11-21 22:54:45 -05:00
satotake
ce8a88416d Merge branch 'trunk' into builtins-list-intersperse 2021-11-18 11:16:27 +00:00
satotake
16fb04b4fa Add builtin List.intersperse 2021-11-17 15:18:45 +00:00
satotake
73dda714de Add builtin List.split 2021-11-15 13:50:11 +00:00
Folkert de Vries
b3a663a741
Merge branch 'trunk' into builtins-list-sublist 2021-11-10 16:28:58 +01:00
satotake
c0a362dc1a fix solve_expr test 2021-11-10 14:32:22 +00:00
satotake
9f5d3f521b Implement List.sublist 2021-11-10 13:16:57 +00:00
Michael Downey
07cd3850d7
Merge branch 'trunk' into str_trim_left 2021-11-09 19:43:26 -05:00
Michael Downey
eeab43ba13 fixing line for cargo fmt 2021-11-09 15:02:16 -05:00
Michael Downey
1f74fd6856 fixing formatting and adding str_trim_left back to solve_expr 2021-11-09 14:57:35 -05:00
Michael Downey
c0c45f6d39 correct trim to trimLeft in solve_expr 2021-11-09 14:34:24 -05:00
Michael Downey
1bc278d962 initial commit of Str.trimLeft 2021-11-09 14:25:24 -05:00
satotake
772fc9c021 Implement List.takeLast 2021-11-09 12:26:17 +00:00
satotake
878400f95f Implement List.takeFirst 2021-11-08 14:10:53 +00:00
Dan Knutson
352fe90e2d fix format violation 2021-10-26 18:14:04 -05:00
Folkert de Vries
29bd4e3e50
Merge branch 'trunk' into str_trim 2021-10-26 22:45:32 +02:00
Dan Knutson
46365da73a add failing tests
* SIGSEGV for non-empty strings
2021-10-25 20:22:37 -05:00
Chelsea Troy
fc55172219
Fix test typo 2021-10-25 10:45:18 -05:00
Chelsea Troy
49a832d757
Add dropLast to tests and parser 2021-10-21 23:02:26 -05:00
Folkert
4b65430bef fix test 2021-10-17 16:32:45 +02:00