Commit Graph

143 Commits

Author SHA1 Message Date
ayazhafiz
597a1cef3b Attach location to alias header name 2021-12-26 09:17:27 -06:00
ayazhafiz
11da888c07 Pull out alias header as its own struct 2021-12-26 09:07:12 -06:00
ayazhafiz
2cd5bf8c03 Parse "as" aliases into tag/args rather than arbitrary annotations 2021-12-26 08:44:09 -06:00
Richard Feldman
ed34af2677
Merge pull request #2225 from rtfeldman/editor-docs
Added more editor documentation
2021-12-24 08:54:57 -05:00
ayazhafiz
d5bd58c298 First pass on presence constraints in Ast2 2021-12-23 20:22:20 -06:00
ayazhafiz
1f81a598f7 Presence constraint flag -> Enum 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
Joshua Warner
22e2545fd6 format 2021-12-22 20:46:42 -08:00
Joshua Warner
4d7070ce3b Always combine line,column into Position 2021-12-22 20:32:46 -08:00
Joshua Warner
f19220473a Rename Located -> Loc 2021-12-22 19:18:22 -08: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
Anton-4
1e04724427 added more editor documentation 2021-12-15 20:00:51 +01:00
Anton-4
64ccf8a870 minor cleanup 2021-12-09 14:14:20 +01:00
Anton-4
8c82025721 Merge branch 'trunk' of github.com:rtfeldman/roc into editor-comments 2021-12-09 13:55:44 +01:00
Anton-4
9a2187ecd2 fixed newline issues 2021-12-09 13:55:18 +01:00
Anton-4
7fb00140c1
Merge pull request #2115 from rtfeldman/arraystring
fixes for arraystring insertion PR
2021-12-08 10:04:39 +01:00
Folkert
41c5d53ef9 ignore 'large enum variant' for now 2021-12-05 15:28:24 +01:00
Folkert
4af9539ce6 fixes by cargo clippy --fix 2021-12-05 15:04:28 +01:00
Anton-4
b3420d793f removed dbg, disabled comment_after test 2021-12-04 15:22:45 +01:00
Anton-4
d6a27d1e53 Merge branch 'trunk' of github.com:rtfeldman/roc into editor-comments 2021-12-04 11:00:03 +01:00
Anton-4
2a97d09299 optimization + bug fix 2021-12-03 13:32:36 +01:00
Brendan Hansknecht
67f5826c48 use byte array to avoid allocation when using arrstring 2021-12-02 09:47:58 -08:00
Chelsea Troy
f680ee3c24 Fix a spelling mistake; how was this ever passing? 2021-12-01 18:41:37 -06:00
Anton-4
5bd776f972 debugging inline comment bug 2021-12-01 16:57:28 +01:00
Anton-4
0ac622e9ff use ArrayString more often 2021-12-01 11:13:58 +01:00
Anton-4
038c296891 replaced ArrayString with arrayvec 2021-11-30 14:06:36 +01:00
Chelsea Troy
6cf755ad8d Resolve a bunnnch of merge conflicts 2021-11-29 23:14:29 -06: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
ba678d924d Remove unused variables 2021-11-25 11:16:18 -05:00
ayazhafiz
fe85af8d03 Fix failing compilation in Expr2 2021-11-25 11:16:18 -05:00
Anton-4
30c1d218a7 started on supprting comments in editor+docs 2021-11-23 20:03:25 +01:00
Folkert
2c1005fdf0 remove lowercases from Content 2021-11-22 21:15:58 +01:00
ayazhafiz
d4b2f17ac5 Implement inference variable solving in Expr2
Part of #1804
2021-11-21 23:20:40 -05:00
Folkert de Vries
71233fcfc1
Merge pull request #2012 from rtfeldman/i/1714
Take syntactic sugar into account when reporting errors
2021-11-19 10:26:24 +01:00
Folkert de Vries
a58c999d3e
Merge pull request #2008 from rtfeldman/improve-typo-suggestions
Minor improvements to "did you mean?" suggestions provided for missing identifiers
2021-11-19 10:24:52 +01:00
ayazhafiz
fe99d20be5 Apply review suggestions 2021-11-18 21:49:37 -05:00
ayazhafiz
8b7217847d Rename additional stale roc_module::operator refs and format 2021-11-18 20:20:33 -05:00
ayazhafiz
8a60162a1e Rename roc_module::operator -> roc_module::called_via
A bit of a nit, but this file is now more general than just keeping
track of operator methods.
2021-11-18 20:20:33 -05:00
ayazhafiz
30955a1eb8 Take syntactic sugar into account when reporting errors
Previously, a program like

```roc
word = "word"

if True then 1 else "\(word) is a word"
```

would report an error like

```
── TYPE MISMATCH ───────────────────────────────────────────────────────────────

This `if` has an `else` branch with a different type from its `then` branch:

3│  if True then 1 else "\(word) is a word"
                        ^^^^^^^^^^^^^^^^^^

This concat all produces:

    Str

but the `then` branch has the type:

    Num a

I need all branches in an `if` to have the same type!
```

but this is a little bit confusing, since the user shouldn't have to
know (or care) that string interpolations are equivalent to
concatenations under the current implementation.

Indeed we should make this fully transparent. We now word the error
message by taking into account the way calls are made. To support the
case shown above, we introduce the `CalledVia::Sugar` variant to
represent the fact that some calls may be the result of desugaring the
surface syntax.

This commit also demonstrates the usage of `CalledVia` to produce better
error messages where we use binary comparison operators like `<`. There
are more improvements we can make here for all `CalledVia` variants, but
this is a good starting point to demonstrate the usage of the new
procedure.

Closes #1714
2021-11-18 20:20:33 -05:00
Folkert
9aca302c39 Merge remote-tracking branch 'origin/trunk' into deep-copy-var-to 2021-11-18 13:16:24 +01:00
ayazhafiz
3d601ac02d Ensuer RuntimeError::ValueNotExposed is built properly in roc_ast 2021-11-17 22:58:16 -05:00
Joshua Warner
7f5b873357 Parse _ in type annotations as an 'Inferred' type 2021-11-17 17:59:40 -08:00
ayazhafiz
111a835b3c Add ignored tests for annotation-only declarations in Expr2
These tests fail currently because we have not implemented type
reconstruction in the presence of annonation-only declarations, but it's
good to keep track of them for later.
2021-11-17 13:38:00 -05:00
ayazhafiz
539c737123 Implement constraint generation for annotated Expr2::FunctionDefs
This is mostly the same as the procedure for unannotated `FunctionDef`s.
The only differences are that we need to

1. note the rigid type variables that are a part of the FunctionDef
2. generate fresh type variables for the function arguments, and
   constrain them to the types of the arguments passed to us in the
   annotation

This is enough to get the constraint generation working. There are more
interesting cases that properly typecheck in the main compiler but do
not typecheck given the current state of the editor AST (see the second
test in this commit), but this is a bug due to canonicalization, not
type reconstruction.
2021-11-17 13:38:00 -05:00
ayazhafiz
9399596d86 Store rigid var names during translation of closure defs to Expr2
We ened to store the mapping of `rigid type vars -> user-declared names`
for presentation later on when we reconstruct the type of an expression
and want to pretty-print it for the user. This information is most
naturally captured on `output.introduced_variables`, as the main
compiler does so there.

We don't currently record this mapping while translating `Annotation`s
to `Annotation2`s (though we could), so we store it when we hit an
annotated expression that now needs to become an `Expr2`.
2021-11-17 13:38:00 -05:00
ayazhafiz
477ecd6c3b Store rigid type and field names as Lowercase in Expr2
Moving from storing these as slices to `Lowercase`s makes it easier to
transform to shapes we'll need later during type reconstruction, for
example a mapping of rigid type variables to their lowercase variable
names.
2021-11-17 13:38:00 -05:00
ayazhafiz
efe6a8b7c8 Pass down rigids vars for substitution during type reconstruction
Rigid vars are added to types after solutions are already found and are
only relevant for pretty printing elaborated types, so we don't keep
track of/care about their rigid names until the end of solution.
Previously we didn't provide this information in tests, though - now we
do.
2021-11-17 13:38:00 -05:00
ayazhafiz
506086e3d7 Make sure Expr2 function annotation arguments fit in a PoolVec slot
The size of a `(PatternId, Type2)` tuple is 40 bytes (4 for the
`PatternId`, 4 bytes padding, 32 for the `Type2`). This doesn't fit in
an item slot allocated by the pool, which has a max of 32 bytes. So, we
allocate the Type2 itself on the pool, and then reference its pool ID in
the resulting tuple, which lowers the total size of the tuple to 8
bytes. This is a bit wasteful, but I couldn't find a better solution
without significantly more rework.

We also reorder the Type2 and PatternId fields in the tuple to better
align with the typical `(type|type variable, pattern|expression)` tuple
structure that exists in e.g. `FunctionDef::NoAnnotation`.
2021-11-17 13:38:00 -05:00
ayazhafiz
af8fad2618 Update sizes of Type2 variants to be correct
These are outdated; the new calculations reflect the current state of
the codebase.
2021-11-17 13:38:00 -05:00
Folkert
e6c561de7a Merge remote-tracking branch 'origin/trunk' into deep-copy-var-to 2021-11-17 16:34:01 +01:00
Folkert
237d8d1c0b fix the Default instance for subs
we later rely on some variables always existing (numbers, empty record, empty tag union)
but the default instance did not insert those
2021-11-17 16:29:16 +01:00
ayazhafiz
f342bb03af Resolve clippy lints 2021-11-16 16:20:40 -05:00
ayazhafiz
3fe29c9949 Implement constraint generation for Expr2::LetFunction
We do this by treating function definition bodies as equivalent to
closures, and piggy-backing on existing work to generate constraints
over closures. Then, we just bind the function name with the resolved
type of the function body.

Support for constraint generation in the presence of annotated functions
will be added later.
2021-11-16 15:26:47 -05:00
ayazhafiz
b824302ab3 Name resolved type variables during Expr2 constrain testing
Prior to this patch we would not explicitly name solved type variables,
causing the elaborated type to appear unconstrained even when the
internal representation was constrained. For example, given a definition
like

```
\a, b -> Pair a b
```

we would generate distinct, fresh type variables for `a` and `b` but not
name them after solution. So even though the compiler knows they are
distinct, printing to the surface syntax would emit

```
*, * -> [ Pair * * ]*
```

which is incorrect, as the result type is constrained on the input type.
Instead, we now properly emit

```
a, b -> [ Pair a b ]*
```

naming variables where dependencies do exist. Where type variables are
don't constrain anything else, we can and do continue to emit the
wildcard type.
2021-11-16 11:56:39 -05:00
Joshua Warner
1fabc64fdf Use Collection in Expr::TagUnion 2021-11-13 07:38:39 -08:00
Joshua Warner
d63405d824 Make Expr::List use a Collection 2021-11-13 07:38:11 -08:00
Joshua Warner
a4ca6a31a6 Use Collection in Expr::Record and related places 2021-11-13 07:36:05 -08:00
Joshua Warner
4df0880e7a Commit local changes (whoops!) 2021-11-11 18:57:26 -08:00
Joshua Warner
04d4a8ca79 Introduce Collection as a general abstraction in the ast 2021-11-11 14:49:33 -08:00
Anton-4
053fbbba0b
add unicode TODO 2021-11-11 09:52:11 +01:00
rvcas
af6c0a1be0 chore: document the assert with a document 2021-11-07 17:24:20 -05:00
rvcas
5f7823538a feat: make pool pointer operations sound 2021-11-07 11:51:37 -05:00
Brendan Hansknecht
73e2cbcb1e Make versions numbers consistent and matching the lock files 2021-11-06 13:24:45 -07:00
Anton-4
69f6ffadab
Merge branch 'trunk' into deps 2021-11-06 18:07:34 +01:00
Kevin Sjöberg
f6d055dc62 Correct minor spelling mistakes 2021-11-06 15:29:08 +01:00
Brendan Hansknecht
bddc08c977 Remove unused dependencies 2021-11-05 16:58:11 -07:00
Richard Feldman
0bc3ff4ca5 Use std and core over libc where equivalent 2021-11-02 19:37:05 -04:00
Richard Feldman
ffbf2b4276 Move some things to dev deps 2021-11-02 19:37:05 -04:00
Anton-4
bb715e0f84 cleanup 2021-10-19 17:51:47 +02:00
Anton-4
c7c421b2f5 fixed scope lookup bug 2021-10-19 16:45:28 +02:00
Anton-4
0a77b3f334 debugging wrong id in docs test 2021-10-18 19:58:03 +02:00
Anton-4
a272765fc7 started using scope properly, improved error backtrace conversion 2021-10-16 19:37:20 +02:00
Anton-4
2158686a0a fmt, improved todo 2021-10-15 19:29:48 +02:00
Anton-4
d3f2b95f7a addes test to docs for function 2021-10-15 15:02:37 +02:00
Anton-4
428b4574ae Merge branch 'trunk' of github.com:rtfeldman/roc into function_closure_to_mark_node 2021-10-15 12:04:51 +02:00
Anton-4
0058037ed2 bugfixes 2021-10-13 17:41:26 +02:00
Anton-4
4828c9ba62 fmt 2021-10-13 12:37:30 +02:00
Anton-4
810c7dce80 bug fixes 2021-10-12 20:16:03 +02:00
Anton-4
37ba50e746 bug fixes involving IdentId 2021-10-11 20:16:22 +02:00
Anton-4
03d9d41a7a debugging closure -> MarkupNode 2021-10-08 20:19:52 +02:00
Anton-4
11417c0624 refactoring, started on converting function closure to MarkNode 2021-10-06 20:27:42 +02:00
Anton-4
4324b08a30 cleanup+fmt+clippy 2021-10-05 11:58:11 +02:00
Anton-4
548d806a88 def->MarkupNode working 2021-10-04 19:26:31 +02:00
Anton-4
28cf11a1d9 started on docs to markup to html 2021-09-29 20:05:03 +02:00
Anton-4
358664a51a minor cleanup 2021-09-25 19:27:48 +02:00
Anton-4
95a30210ce clippy fixes, fmt 2021-09-25 19:17:12 +02:00
Anton-4
4c2de0215a tests working 2021-09-25 18:38:04 +02:00
Anton-4
69391b26d7 removed lang and markup folder from editors, changed imports to use new crates 2021-09-25 17:14:32 +02:00
Anton-4
f9e2e3469b separated markup and util crates, no more errors 2021-09-24 20:08:49 +02:00
Anton-4
ea62f15ac6 no more errors 2021-09-24 15:41:45 +02:00
Anton-4
43fc0f87ad fixed many imports after refactoring 2021-09-24 15:14:34 +02:00
Anton-4
59831f2e85 more refactoring for seperate ast crate 2021-09-22 21:02:43 +02:00