Commit Graph

167 Commits

Author SHA1 Message Date
Ayaz Hafiz
62ebb80f09
Handle recursion through Applys with errors
Closes #219
2022-05-10 12:58:14 -04:00
Ayaz Hafiz
5a5fc0162d FlexAble must always constrain a Flex 2022-05-08 15:08:18 -04:00
Ayaz Hafiz
9964f86a3d
Factor bespoke debug variables into debug_flags crate 2022-04-29 17:45:55 -04:00
Ayaz Hafiz
afe49cf570 Cleanup 2022-04-28 20:34:04 -04:00
Ayaz Hafiz
b6383f81ee
Numbers are opaques 2022-04-25 10:59:42 -04:00
Ayaz Hafiz
969d14dfe9
I love 50 arguments 2022-04-25 10:59:42 -04:00
Ayaz Hafiz
8b291854d3
Improve alias<->opaque unification logic 2022-04-25 10:59:40 -04:00
Ayaz Hafiz
bb06bcd7f1
Fix compile error 2022-04-22 17:57:02 -04:00
ayazhafiz
939f413569
Don't try to fix recursion vars if there are other errors 2022-04-22 17:57:02 -04:00
Ayaz
3906c5c200
Clippy 2022-04-22 17:57:01 -04:00
Ayaz Hafiz
b61481c6e7
Try another strategy - fix recursion vars during typechecking 2022-04-22 17:57:01 -04:00
Ayaz Hafiz
11f29baf25
Add note about output 2022-04-21 09:34:40 -04:00
Ayaz Hafiz
21661275d8
Show unified variables as a tree 2022-04-21 09:32:26 -04:00
Ayaz Hafiz
9d71a3d1ac
Generalizing ability type instance to ability is illegal
Closes #2881
2022-04-20 17:45:40 -04:00
Ayaz Hafiz
e0c9931326
Bugfix debug printing 2022-04-18 10:21:56 -04:00
Richard Feldman
718b999751
Merge pull request #2857 from rtfeldman/abilities-mono
Codegen for abilities
2022-04-16 22:59:16 -04:00
Ayaz Hafiz
00e5205d4c
More debugging for unified types 2022-04-15 09:53:23 -04:00
Ayaz Hafiz
7d4a006377
Bugfix sorting must implement constraints
Also makes things go faster
2022-04-15 09:29:12 -04:00
Ayaz Hafiz
fbe7ccf4c8
Use error macro 2022-04-15 08:51:29 -04:00
Ayaz Hafiz
b79b351136
The first ability... compiles 2022-04-14 16:50:41 -04:00
Ayaz Hafiz
15a040ec87
Basic type inference and solving for abilities
Note that is still pretty limited. We only permit opaque types to
implement abilities, abilities cannot have type arguments, and also no
other functions may depend on abilities
2022-04-12 16:18:07 -04:00
Ayaz Hafiz
913d97cab1
Add needed imports 2022-04-12 16:18:07 -04:00
Ayaz Hafiz
886e5a0c8f
Don't unify real vars when there are no type variables, or nothing changed 2022-04-05 17:51:30 -04:00
Ayaz Hafiz
163c6b39d6
Unify type alias "real variables"
Turns out that we can't always assume that a successful unification of
type alias type variables means that those aliases had the same real
type from the start. Because type variables may contain unbound type
variables and grow during their unification (for example,
`[InvalidNumStr]a ~ [ListWasEmpty]b` unify to give `[InvalidNumStr,
ListWasEmpty]`), the real type may grow as well.

For this reason, continue to explicitly unify alias real types for now.
We can get away with not having to do so when the type variable
unification causes no changes to the unification tree at all, but we
don't have a great way to detect that right now (maybe snapshots?)

Closes #2583
2022-04-05 11:21:52 -04:00
Folkert
0dd2cec09a
update with new clippy lints 2022-03-31 19:34:51 +02:00
Folkert
7062a71216
clippy 2022-03-20 21:42:04 +01:00
Folkert
7d8409f6a6
write Aliases implementation 2022-03-15 22:02:04 +01:00
ayazhafiz
5670fe06cd Deal with destructuring tag unions behind opaques correctly
Closes #2702
2022-03-13 18:44:38 -05:00
Folkert
a9c8e2dc3e
copy instead of clone Content 2022-03-06 19:07:18 +01:00
Folkert
1ff8261a66
make Content Copy 2022-03-06 18:51:23 +01:00
ayazhafiz
07b1829732 Improve error reporting for patterns not matching opaques 2022-02-27 00:11:11 -05:00
ayazhafiz
736645cd8c Remove some dead code 2022-02-27 00:10:12 -05:00
ayazhafiz
059c324268 Error reporting for type mismatches involving opaques 2022-02-27 00:10:12 -05:00
ayazhafiz
0d241f3c3c Only expand ErrorType::Range's type range when range unification fails 2022-02-06 15:04:13 -05:00
ayazhafiz
aaac22f6c2 Respell typo 2022-02-06 15:04:13 -05:00
ayazhafiz
ff3596505e Fix gen tests 2022-02-06 15:04:12 -05:00
ayazhafiz
680bf8e0b7 Treat rigids as flex vars when checking number range types 2022-02-06 15:04:12 -05:00
ayazhafiz
6d72971d6b Clippy and a ranged number unification bugfix 2022-02-06 15:04:12 -05:00
ayazhafiz
364d2585df Fix repl tests 2022-02-06 15:04:12 -05:00
ayazhafiz
8dc92ccd97 Second pass 2022-02-06 15:04:12 -05:00
ayazhafiz
e54917a063 Expose type mismatches between recursive types and types that aren't
Closes #2166
2022-01-30 00:21:45 -05:00
Folkert
2c97c840fc walk the chain till we find a tag union to make recursive 2021-12-31 14:26:23 +01:00
ayazhafiz
52c84824ba Fix typo 2021-12-23 19:40:18 -06:00
ayazhafiz
1f81a598f7 Presence constraint flag -> Enum 2021-12-23 19:40:18 -06:00
ayazhafiz
8dda9929e5 Fix clippy warning 2021-12-23 19:40:18 -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
d6184e5529 1-branch match -> "if let" 2021-12-22 18:01:53 -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
28b4388488 remove unneeded field 2021-12-05 15:25:46 +01:00
Folkert
4957b84eae remove unused struct in unify 2021-12-05 15:19:39 +01:00