Commit graph

220 commits

Author SHA1 Message Date
Ayaz Hafiz
9f45c2ff47
Correctly copy non-generalized imports as non-generalized
Importing a rigid variable in a non-generalized context should not keep
the variable as rigid. That's because rigid variables are only necessary
for enforcing invariants during typechecking of a generalizable
definition, but at all use sites (which are not generalized), they are
demoted to possibly-unbound type variable.
2023-05-24 14:12:24 -05:00
Ayaz Hafiz
d3120e500e
Drop translations key 2023-05-24 14:06:39 -05:00
Richard Feldman
922a10db52
Merge pull request #5389 from agu-z/agu-z/record-builder-syntax
Record Builder Syntax
2023-05-13 22:47:03 -04:00
Agustin Zubiaga
71a2990e21 Tip replacing <- with : for static values 2023-05-09 23:37:24 -03:00
Folkert de Vries
ec21f19826
Merge pull request #5374 from GabrielDertoni/remove-needless-string-alloc
refactor: remove needless string allocation in pretty printer
2023-05-06 00:34:48 +02:00
Gabriel Dertoni
7d0027f428
refactor: remove needles string allocation in pretty printer
Many times, in order to create a `ven_pretty::Doc` containing a text
node, the pattern `alloc.text(format!(...))` would be used. This code
then creates a fresh string that is then used in the `Doc`. However,
many times only a small string is necessary and so the allocation could
be optimized. The `ven_pretty` crate supports this through a `SmallString`
type. Allocating a fresh string with `format!` also moves control away
from the `DocAllocator` which isn't ideal, since it could also handle
the string allocations. So, instead of creating a fresh string, one can
simply call `alloc.as_string(format_args!(...))` and delegate the
allocation to the `DocAllocator` without any loss in expressivity. So,
in order to encorage this pattern, this commit also introduces the
`text!` macro.

In order to find all instances of the code pattern, the following
tree-sitter query was used:

```scm
(call_expression
    function: (field_expression
        field: (field_identifier) @field.name
               (#eq? @field.name "text"))
    arguments: (arguments
        (macro_invocation
            macro: (identifier) @macro.name
            (#eq? @macro.name "format")))) @reference.call
```
2023-05-03 21:28:36 -03:00
Ayaz Hafiz
df3bd79d4a
Simplify occurs check for aliases 2023-05-02 17:00:58 -05:00
Ayaz Hafiz
8ca1e6c866
Correct occurs cycle under alias argument but not alias real var
At times we can have alias arguments that are recursive in their
position, but whose recursiveness is not immediately visible in the real
var.

Closes #5330
2023-05-02 17:00:58 -05:00
Ayaz Hafiz
d13e221678
Print variables if asked to 2023-05-02 13:08:58 -05:00
Ayaz Hafiz
5ec2715820
Correctly introduce new recursion variables at the correct rank 2023-05-01 13:14:59 -05:00
Ayaz Hafiz
7beee4e1f3
Add a way to print ranks in uitest 2023-05-01 13:14:59 -05:00
Folkert
4cd8f0a056 clippy --fix fixes 2023-04-21 12:05:51 +02:00
Ayaz Hafiz
d3ab9ab926
Freshly instantiate nested recursion variables under an opaque type 2023-04-12 14:31:19 -05:00
Ayaz Hafiz
40fc920b5e
Drop recursion var instantiation in the wrong spot 2023-04-12 14:12:36 -05:00
Ayaz Hafiz
f33651bf6a
Correctly instantiate recursion variables under nested aliases
Like we instantiate nested lambda set variables and nested OIOP
variables for aliases, we need to do the same for recursion variables.
2023-04-12 13:59:24 -05:00
Ayaz Hafiz
73e5a9ed46
Remove unused branch in alias instantiation 2023-04-12 13:17:42 -05:00
Ayaz Hafiz
8e093abaf5
Reduce loop to while 2023-04-10 16:36:18 -05:00
Ayaz Hafiz
b9ab93fd98
Introduce annotation in first step of recursive solving independently
The algorithm for solving recursive definitions proceeds in several
steps. There are three main phases: introduction of what's known,
solving what's not known, and then checking our work of what was
inferred against what the programmer claimed. Concretely:

1. All explicitly-annotated signatures in the mutually recursive set are
   introduced and let-generalized.
2. Then, inference type variables (`_`) and unannotated def signatures are
   introduced to the cycle, without generalization. The bodies of these
   defs, that are either unannotated or have inference variables, are
   solved.
3. The defs from step (2) are now let-generalized, since we now know
   that their types are consistent. At this point, all the defs in the
   cycle have their types introduced and let-generalized, but we still
   haven't checked the bodies of the defs froom step (1).
4. Check the bodies of explicitly-annotated defs in recursive set. This
   might materially affect the actual types in the signature, for
   example do to fixpoint-fixing or alias expansion.
5. As a result of (4) possibly changing the structure of the annotated
   type, and because the previous annotated types in (1) were introduced
   at a lower rank, we now re-introduce and re-generalize the solved def
   types, in the same we did in step (3).
5. The rest of the program is solved.

Now, a very important thing here is that the annotation signature
introduced for (1) consists of different type variables than the
annotation signature introduced in (5). The reason is that they live at
different ranks. Prior to this patch we were not explicilty doing so;
this commit ensures that we do.
2023-04-10 16:31:00 -05:00
Brendan Hansknecht
c440b2ca05
Switch to PathBuf to avoid Path turning into a fat pointer. Avoids growing Constraints 2023-04-09 21:14:05 -07:00
Brendan Hansknecht
6302a8d4b5
switch from type annotation to type variable 2023-04-09 14:03:33 -07:00
Brendan Hansknecht
7079361841
add ingested file category for error messages 2023-04-09 14:03:32 -07:00
Ayaz Hafiz
4d789cd0c6
Get content unchecked in occurs check 2023-04-07 20:24:04 -05:00
Ayaz Hafiz
e6be13052b
Correct order of cached occurs check 2023-04-07 20:19:58 -05:00
Ayaz Hafiz
a816f8bc83
Do not revisit variables in an occurs check
Turns out this mark cache check is unreasonably effective, even if it
is naive.
2023-04-06 14:42:31 -05:00
Ayaz Hafiz
18858b9eb3
Get rid of inaccurate debug assertion 2023-03-28 14:19:43 -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
c32bc5f152
Offset tuple element indices correctly when importing 2023-03-22 10:52:31 -05:00
Ayaz Hafiz
240c1f35d6
Ranged number abilities are derived and compiled correctly
Closes #5089
2023-03-22 09:42:06 -05:00
Brendan Hansknecht
f42f61e271
run a toml formatter and then clean it up a bit 2023-03-06 19:47:57 -08:00
Brendan Hansknecht
4a89bee0a5
centralize package versions except for vendor and excluded 2023-03-06 19:29:09 -08:00
Brendan Hansknecht
5485c8a5b0
update to using workspace package spec 2023-03-06 16:36:18 -08:00
Ayaz Hafiz
b406e384fc
Print recursion variables correctly in pretty printer 2023-02-13 17:42:21 -06:00
Ayaz Hafiz
4844c278a8
Be sure to correctly print multiple unrelated recursion structures as needed 2023-02-13 17:15:34 -06:00
Joshua Warner
5a6be05ead
implement mono / lowering for tuples 2023-02-07 18:54:50 -08:00
Ross Smyth
4698608c4d Atomic ordering for debug counter is stricter than nesscessary. 2023-01-30 11:10:18 -05: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
91d61424ad
Lints 2023-01-16 10:54:39 -06: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
1c93727822
Add a notion of "openness" tag extensions suitable only for size-polymorphism 2023-01-16 10:52:23 -06:00
Ayaz Hafiz
5f5d6a42d1
Add debug assertion for shape of tag union extension variables
When we have a tag union type, outside of special cases in the middle of
unification, its extension type should either be (1) the closed tag
union or (2) a flex/rigid var. This adds an assertion for that.
2023-01-16 10:52:23 -06:00
Ayaz Hafiz
beb7e79830
Print extension vars that are ability-bound 2023-01-14 15:33:54 +01:00
Folkert de Vries
e3a213c0dc
Merge pull request #4882 from roc-lang/weakening-3
Begin weakening let-bindings to non-function, non-number expressions
2023-01-14 15:32:27 +01:00
Ayaz Hafiz
b2cdddbdfb
Weaken lists 2023-01-12 10:02:20 -06:00
Richard Feldman
dc8eb81bb2
Omit more unnecessary fields from record diffs 2023-01-11 23:18:53 -05:00
Ayaz Hafiz
d214598a16
Rename rank none to rank generalized 2023-01-11 14:55:18 -06:00
Ayaz Hafiz
3b0e2429e6
Support printing weak type variables in tests
Unbound type variables that are not at the generalization rank will now
be printed as `w_a` in solve tests.
2023-01-04 16:24:19 -06:00
Ayaz Hafiz
5b9e3aa856
Handle error types in record/tag extensions when printing errors 2022-12-27 13:20:28 -06:00
Ayaz Hafiz
cd2b936a59
Ensure that disjoint nested lambda sets force parents to be disjoint
We must be careful to ensure that if unifying nested lambda sets
results in disjoint lambdas, that the parent lambda sets are
ultimately treated disjointly as well.
Consider

```
  v1: {} -[ foo ({} -[ bar Str ]-> {}) ]-> {}
~ v2: {} -[ foo ({} -[ bar U64 ]-> {}) ]-> {}
```

When considering unification of the nested sets

```
  [ bar Str ]
~ [ bar U64 ]
```

we should not unify these sets, even disjointly, because that would
ultimately lead us to unifying

```
v1 ~ v2
=> {} -[ foo ({} -[ bar Str, bar U64 ]-> {}) ] -> {}
```

which is quite wrong - we do not have a lambda `foo` that captures
either `bar captures: Str` or `bar captures: U64`, we have two
different lambdas `foo` that capture different `bars`. The target
unification is

```
v1 ~ v2
=> {} -[ foo ({} -[ bar Str ]-> {}),
         foo ({} -[ bar U64 ]-> {}) ] -> {}
```

Closes #4712
2022-12-12 14:51:18 -06:00