Commit graph

505 commits

Author SHA1 Message Date
Folkert
afd11e1cb1 move target -> roc_target 2022-01-26 23:33:29 +01: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
409ced0ef2 Simply constraint matching in solve 2021-12-23 20:22:42 -06:00
ayazhafiz
1f81a598f7 Presence constraint flag -> Enum 2021-12-23 19:40:18 -06:00
ayazhafiz
b4c9068676 Make pattern presence constraints an enum variant 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
Folkert de Vries
5f7476d54f
Merge pull request #2266 from rtfeldman/joshuawarner32/loc
Parser refactor: always group (Row, Col) into Position
2021-12-24 00:02:13 +01:00
Folkert de Vries
db44d03e66
Merge pull request #2259 from rtfeldman/i/2227-record-layout-hang
Turn invalid record field types into runtime errors
2021-12-23 20:17:34 +01:00
Joshua Warner
f19220473a Rename Located -> Loc 2021-12-22 19:18:22 -08: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
ayazhafiz
576f1293fd Turn invalid record field types into runtime errors
By emitting a runtime error rather than panicking when we can't layout
a record, we help programs like

```
main =
    get = \{a} -> a
    get {b: "hello world"}
```

execute as

```
Mismatch in compiler/unify/src/unify.rs Line 1071 Column 13
Trying to unify two flat types that are incompatible: EmptyRecord ~ { 'a' : Demanded(122), }<130>

🔨 Rebuilding host...
── TYPE MISMATCH ───────────────────────────────────────────────────────────────

The 1st argument to get is not what I expect:

8│      get {b: "hello world"}
            ^^^^^^^^^^^^^^^^^^

This argument is a record of type:

    { b : Str }

But get needs the 1st argument to be:

    { a : a }b

Tip: Seems like a record field typo. Maybe a should be b?

Tip: Can more type annotations be added? Type annotations always help
me give more specific messages, and I think they could help a lot in
this case

────────────────────────────────────────────────────────────────────────────────

'+fast-variable-shuffle' is not a recognized feature for this target (ignoring feature)
'+fast-variable-shuffle' is not a recognized feature for this target (ignoring feature)
Done!
Application crashed with message

    Can't create record with improper layout

Shutting down
```

rather than the hanging

```
Mismatch in compiler/unify/src/unify.rs Line 1071 Column 13
Trying to unify two flat types that are incompatible: EmptyRecord ~ { 'a' : Demanded(122), }<130>

thread '<unnamed>' panicked at 'invalid layout from var: UnresolvedTypeVar(104)', compiler/mono/s
rc/layout.rs:1510:52
```

that was previously produced.

Part of #2227
2021-12-21 19:11:59 -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
Folkert
27269faa0b optimize alias to var conversion 2021-12-01 18:39:45 +01:00
rvcas
40090f20e6 test: update tests to use Num.toStr 2021-11-30 14:56:08 -05:00
Richard Feldman
d39ecfd12d
Merge pull request #2052 from rtfeldman/i/1931-2
Some improvements to error messages regarding unbound type variables
2021-11-26 21:17:37 -05:00
Folkert
6934e69240 make deep_copy_var_to allocate less 2021-11-27 02:09:08 +01:00
Folkert
471593ea31 make deep_copy_var use scratchpad arena 2021-11-27 01:32:47 +01:00
Folkert
2d0d54e13e try stack allocation for small vectors 2021-11-27 01:31:48 +01:00
Folkert
b4f21930bb cleanup 2021-11-25 20:49:44 +01:00
Folkert
612f868652 make VariableSubsSlice an alias 2021-11-25 20:29:34 +01:00
ayazhafiz
d352d2cdf8 Revert "Include annotation type signatures in Expected struct"
This reverts commit 6e4fd5f06a1ae6138659b0073b4e2b375a499588.

This idea didn't work out because cloning the type and storing it on a
variable still resulted in the solver trying to uify the variable with
the type. When there were errors, which there certainly would be if we
tried to unify the variable with a structure that had nested flex/rigid
vars, the nested flex/rigid vars would inherit those errors, and the
program wouldn't typecheck.

Since the motivation here was to expose the signature type to
`reporting` so that we could modify it with suggestions, we should
instead pass that information along in something analogous to the
`Expected` struct.
2021-11-25 13:24:42 -05:00
ayazhafiz
a8e38172ac Remove redundant refs 2021-11-25 11:22:19 -05:00
ayazhafiz
ee34e79790 Include annotation type signatures in Expected struct
To provide better error messages and suggestions related to changing
type annotations, we now pass annotation type signatures all the way
down through the constraint solver. At constraint generation we
associate the type signature with a unique variable, and during error
reporting, we pull out an `ErrorType` corresponding to the original type
signature, by looking up the unique variable. This gives us two nice
things:

1. It means we don't have to pass the original, AST-like type
   annotation, which can be quite large, to everyone who looks at an
   expectation.
2. It gives us a translation from a `Type` to an `ErrorType` for free
   using the existing translation procedure in `roc_types::subs`,
   without having to create a new translation function.
2021-11-25 11:16:17 -05:00
Richard Feldman
618925fe27
Fix typo in comment 2021-11-24 23:17:24 -05:00
Folkert
093b733a2c add tag name dedup 2021-11-25 00:11:11 +01:00
Folkert
7c2e8cd812 optimize NAT 2021-11-24 23:00:03 +01:00
Folkert
9c551a0276 use insertion sort 2021-11-24 22:55:45 +01:00
Folkert
e0d7c54906 simplify alias insertion 2021-11-24 22:39:42 +01:00
Folkert
4e4f827bb0 simplify function-or-tag-union insertion 2021-11-24 22:11:05 +01:00
Folkert
379abeed26 refactor tag insertion 2021-11-24 21:57:19 +01:00
Folkert
340055fca5 point to empty VariableSubsSlice 2021-11-24 21:57:00 +01:00
Folkert
cb8e9acb92 special-case the closure tags 2021-11-24 21:14:58 +01:00
Folkert
3e640f78bf cleanup 2021-11-24 20:44:51 +01:00
Folkert
308b91153e add faster insertion path for tag unions 2021-11-24 20:38:52 +01:00
Folkert
541dd9777a thread_local experiment 2021-11-24 19:59:53 +01:00
Folkert
f1541d56bd use Entry in some places 2021-11-24 19:45:30 +01:00
Folkert
5e76e3a97e more reserving into subs 2021-11-24 19:14:37 +01:00
Folkert
739ae60b1e clean up usage of reserve_into_subs 2021-11-24 18:52:22 +01:00
Folkert
61f6687dea fix using the wrong length 2021-11-24 18:50:47 +01:00
Folkert
1fbd2a7e7b reserve variable slices 2021-11-24 16:02:55 +01:00
Folkert
a0c9270124 keep track of visited variables in deep_copy_var 2021-11-24 15:14:17 +01:00
Folkert de Vries
6944c900c2
Merge pull request #2065 from rtfeldman/alias-remove-lowercases
Alias remove lowercases
2021-11-23 10:21:05 +01:00
hafiz
682043c16c
Merge pull request #2063 from rtfeldman/type-to-var-prealloc
preallocate variables to prevent extra vector allocations
2021-11-22 20:05:16 -06:00