Commit graph

288 commits

Author SHA1 Message Date
Ayaz Hafiz
adf961ba0b
Use UEnv where possible 2023-06-22 14:31:49 -05:00
Ayaz Hafiz
ad20a2ee41
Shove more into a common env 2023-06-22 14:31:48 -05:00
Ayaz Hafiz
b5ea2c2c99
s/SolveCtx/SolveConfig/g 2023-06-22 14:31:36 -05:00
Ayaz Hafiz
4f7f66d695
Reorder 2023-06-22 14:31:24 -05:00
Ayaz Hafiz
8314d44650
Break up solve/solve into smaller modules 2023-06-22 14:31:14 -05:00
Ayaz Hafiz
d1dad56331
Rename env to scope 2023-06-22 14:31:03 -05:00
Ayaz Hafiz
683b586f60
Use more structs instead of tuples 2023-06-22 14:31:02 -05:00
Bryce Miller
cb08225bf0
| -> where 2023-06-05 20:19:00 -04:00
Bryce Miller
dbc0204532
abilities syntax has -> implements 2023-05-24 21:30:16 -04:00
Ayaz Hafiz
5ec2715820
Correctly introduce new recursion variables at the correct rank 2023-05-01 13:14:59 -05:00
Ayaz Hafiz
190990155e
Correctly introduce new openness variables at the union rank 2023-05-01 13:14:58 -05:00
Anton-4
e784baccce
rust update, nix update, clippy fixes 2023-04-22 14:51:01 +02:00
Ayaz Hafiz
87a36e62bf
Do not replace already-recursive lambda sets in occurs checks
If a lambda set appears in an occurs chain but it is itself already
recursive, then it is should not be eligibil for modification in the
occurs chain.

Closes #4725
2023-04-12 16:13:30 -05:00
Brendan Hansknecht
165ffcf38d
properly unify ingested file type variable 2023-04-09 14:03:34 -07:00
Brendan Hansknecht
8dd9a5e3c7
correct wrong early return 2023-04-09 14:03:34 -07:00
Brendan Hansknecht
e5b88366fe
add proper error messages for ingested files 2023-04-09 14:03:33 -07:00
Brendan Hansknecht
62fcc71be3
snapshot subs to avoid cloning them 2023-04-09 14:03:33 -07:00
Brendan Hansknecht
2e2b687fac
fix errors with alias analysis 2023-04-09 14:03:33 -07:00
Brendan Hansknecht
6302a8d4b5
switch from type annotation to type variable 2023-04-09 14:03:33 -07:00
Ayaz
8c55e8126d
Merge pull request #5203 from roc-lang/virtual-dom-annotations
Fix a few bugs Virtual-DOM cropped up
2023-03-25 20:00:51 -05:00
Ayaz
1891df77b8
Merge pull request #5188 from roc-lang/i5177
Make sure openness constraint goes under tuples
2023-03-25 15:52:09 -05:00
Ayaz
61dd5cc8c7
Merge pull request #5179 from roc-lang/i5143-tuple-abilities
Implement ability obligation checking and derivation for tuples
2023-03-25 15:51:39 -05:00
Ayaz Hafiz
f37ede036a
Do not adjust rank of lambda sets under alias arguments 2023-03-25 15:21:40 -05:00
Ayaz Hafiz
1b2ee9ad30
Make sure openness constraint goes under tuples
Closes #5177
2023-03-24 14:13:14 -05:00
Ayaz Hafiz
3e83e42195
Make sure to report error rather than descending as appropriate 2023-03-22 17:08:43 -05:00
Ayaz Hafiz
3d2642b282
Stray dbg 2023-03-22 17:08:42 -05:00
Ayaz Hafiz
e6094df69b
Fast-path for determining ability member impls for builtin opaques 2023-03-22 17:08:41 -05:00
Ayaz Hafiz
075332ec88
Run builtin opaques and abilities through derive key 2023-03-22 17:03:57 -05:00
Ayaz Hafiz
dba72c0565
Handle builtin opaque types that implement an ability but don't explicitly list so 2023-03-22 17:03:35 -05:00
Ayaz Hafiz
8a7d9f8f23
Better debugging when lambda set region is missing 2023-03-22 11:13:00 -05:00
Ayaz Hafiz
f4f9ae7a5d
Implement obligation checking of tuples for all abilities 2023-03-22 10:03:01 -05:00
Ayaz Hafiz
63e30443fd
Fix formatting 2023-01-27 17:35:31 -06:00
Ayaz Hafiz
572a666780
No Encode/Decode for Nat 2023-01-27 17:16:10 -06:00
Joshua Warner
303e5bceb3
Fix tuple accessor type printing 2023-01-22 13:22:39 -08:00
Joshua Warner
de828416bf
Initial implementation of tuples in type checking
This leaves in place a bunch of TODOs and likely many bugs - notably, I haven't tested codegen/layout at all here.
2023-01-22 12:40:44 -08:00
Ayaz Hafiz
c9460ecf3f
Rename IsImplicitOpennessVar 2023-01-16 10:52:23 -06:00
Ayaz Hafiz
5fceb9ceb7
Push implicit openness vars through 2023-01-16 10:52:23 -06:00
Ayaz Hafiz
a47841d426
Generalize tag openness extension variables 2023-01-16 10:52:23 -06:00
Ayaz Hafiz
1c93727822
Add a notion of "openness" tag extensions suitable only for size-polymorphism 2023-01-16 10:52:23 -06:00
Ayaz Hafiz
7c4cfba4b8
Rephrase solve comments as per Folkert's review 2023-01-13 12:58:11 -06:00
Folkert de Vries
386983a657
Merge pull request #4881 from roc-lang/rename-rank-none
Rename rank none to rank generalized
2023-01-12 00:25:24 +01:00
Ayaz Hafiz
d214598a16
Rename rank none to rank generalized 2023-01-11 14:55:18 -06:00
Ayaz Hafiz
058644aa96
Implement weakening of variables introduced in branch patterns
Variables introduced in branch patterns should never be generalized in
the new weakening model. This implements that. The strategy is:

- when we have a let-binding that should be weakened, do not introduce
  its bound variables in a new (higher) rank
- instead, introduce them at the current rank, and also solve the
  let-binding at the current rank
- if any of those variables should then be generalized relative to the
  current rank, they will be so when the current rank is popped and
  generalized
2023-01-11 14:28:46 -06:00
Ayaz Hafiz
7febddd1ea
Get rid of unneeded unsafe code and explain max_rank adjustment 2023-01-11 14:28:46 -06:00
Ayaz Hafiz
ddda00036e
Add more comments to solve 2023-01-11 14:28:46 -06:00
Ayaz Hafiz
c2cb94a927
Decide rank to work in for weakening 2023-01-11 14:28:46 -06:00
Ayaz Hafiz
5ccedca093
Implement de-generalization for weakened let bindings 2023-01-11 14:28:45 -06:00
Ayaz Hafiz
cb9f776781
Remove check for redundancy before doing rank adjustment
Presently while generalizing type variables, we check variables
introduced at a scope for redundancy (whether they are not the root of
some unified set of variables). If a variable is redundant, its rank is
not adjusted. I believe the current logic to be the following:

- Each root of a unification tree will be introduced at some point,
  exactly once. Its point of introduction will determine the rank of the
  tree it's the root of
- If a variable is redundant, all of its redundant usages must be at the
  same rank (assuming let generalization proceeds correctly),
  so there is no need to adjust their rank as well
- As such, there is no need to adjust the rank of redundant variables,
  as a performance optimization.

I believe this to be a hold-over from the original version of the solver
derived from the elm-compiler.

In our implementation however rank adjustment is very cheap (thanks to
SoA, ranks are likely in the cache lines already anyway because we just
adjusted variables at this point).

However, there is a larger problem here - ranks must be adjusted for
redundant variables as we begin to support weakened type variables.

The motivating case is

```
\x -> when x is
  _x -> Green
```

we would like this code generalized as `* -> [Green]*`. `when`
expressions have each branch solved via let-bindings; in particular, for
the singleton branch we introduce `_x` of the appropriate type and solve
the body as `[Green]*`.

Today, `[Green]*` would be generalized in the context of the inner scope
that binds `_x`, which means it is generalized in the body `\x -> ...`
as a whole.

However, with weakening, we do not want this behavior! In particular, we
do not want to actually generalize `_x` in the context of the branch
body. Doing so means you could write things like

```
main = \{} -> when Red is
    x ->
        y : [Red]
        y = x

        z : [Red, Green]
        z = x

        {y, z}
```

which is exactly the kind of spurious generalization that the weakening
design is trying to avoid.

So, we want to introduce `[Green]*` at the rank of the body `\x -> ...`;
let's call this `rank_body`, and let's say `[Green]*` is introduced as
`branch_var`. Let's say the return type variable is `ret_var`.

Now we must be careful. If after unification `ret_var ~ branch_var` we have that
`branch_var` becomes the root, then despite `ret_var` (and `branch_var`) being at
`rank_body` (which is also the rank that will promoted to generalization),
the tree given by `branch_var` won't be generalized, because `ret_var` will be
seen as redundant! In fact it is, because `branch_var` was introdued
previously, but that doesn't matter - we want the variable to be
generalized at the level of the outer let-binding `main = \{} -> ...`.

This problem is not unique to when-branches; for example we can observe
the same symptom with

```
main = \{} ->
    x = Green
    x
```

where here we'd like `x` to not be generalized inside the body of
`main`, but have it be generalized relative to the body of `main` (that
is, main should have signature `{} -> [Green]*`, but you cannot use `x`
itself polymorphically inside the body of `main`).

As such, the easiest solution as far as I can see, in the presence of
weakening, is to allow rank-adjustment and generalization of redundant
variables if they are permitted to be generalized relative to a lower
scope.

This should preserve soundness; the main source of unsoundness in
rank-based let generalization is making sure something like

```
\x ->
    y = \z -> x z
    y
```

has type `(a -> b) -> (a -> b)` and not e.g. `(a -> b) -> (c -> d)` due
to `x` being instantiated at a higher rank in `y = ...` than it
actually is. Note that this change cannot affect this case at all, since
we are still doing the rank-adjustment pass at higher ranks, unifying
lowers ranked variables to their minimum relative rank, and introduction
only happens in the lower-ranked scopes.
2023-01-10 12:05:06 -06:00
Ayaz Hafiz
4159b83214
Fix imports 2022-12-03 13:17:35 -08:00
Ayaz Hafiz
2e56405c1e
Fix obligation checking for rigid able vars 2022-12-03 13:17:34 -08:00