1
1
mirror of https://github.com/tweag/nickel.git synced 2024-10-05 15:47:33 +03:00
Commit Graph

535 Commits

Author SHA1 Message Date
Yann Hamdaoui
927ee23993
Update flake inputs (#2058)
Update various flake inputs and the flake.lock file. Adapt the flake.nix
file, as well as the Rust source code, to accomodate the latest changes
(new clippy warnings, etc.).

Topiary is getting hard to use from the flake, because there are two
conflicting versions: the one that is pulled from Nix to be used in the
CI (checking that files are properly formatted), and the one built into
Nickel via cargo. Both must agree (or at least there might be a
difference in formatting between the two if they aren't the same
version). Since the addition of dynamic loading of grammars, latest
Topiary has become harder to build from Nix.

To avoid all those pitfalls, this commit gets rid of the Topiary as a
flake input, and use `nickel format` instead, ensuring that the
formatting is consistent. As a consequence, Topiary isn't included in
the development shell anymore, but it's arguably not an issue: it was
included before `nickel format`, as we needed a third party formatter,
but now one can just build Nickel locally with their preferred method
and use `nickel format`.
2024-10-02 09:12:03 +00:00
jneem
eee41e3dd2
Adds a nickel test subcommand for testing examples in docs. (#2020)
* Doctests

* Add a custom_transform method

* Make the vm private again

* Update doc

* Add some snapshot tests

* Split out closurized and non-closurized variants of eval_record_spine

* Fix doc link

* Add some docs, but not sure where they should go

* Make report_as_str honor the color setting

* Separate the stdout and stderr outputs more intentionally

* Commit the other snapshots
2024-09-26 13:45:03 +00:00
Vitaly Shukela
c50647d281
Explicit imports: import 'Raw "sample.html" (#2036)
* Explicit imports

* explicit import: more changes.

* Rename typ to format
* Bring back the fallback
* Implement pretty-printer part
* Fix compilation of NLP

* Document imports

* Apply suggestions from code review

Co-authored-by: Yann Hamdaoui <yann.hamdaoui@gmail.com>

* minor fix

* explicit imports: add tests

* explicit imports: support importing the same file with different formats

* fmt

* Reinforce explicit imports test against some whitespace changes.

---------

Co-authored-by: Yann Hamdaoui <yann.hamdaoui@gmail.com>
2024-09-18 15:59:48 +00:00
jneem
3663b0af63
Let rec patterns (#2031)
* Add attrs to let patterns

* Implement let-rec patterns

* Fix markdown

* More markdown

* Put a test in the right place

* Revert the comment change

* Review comments
2024-09-12 01:57:15 +00:00
jneem
58412e8e5b
Let blocks (#2010)
* Add let blocks to the AST

* Add parsing and tests

* Fix build

* Missing insta

* Fix it again

* Add a custom parse error

* Try out smallvec

* Support multiple patterns in the ast

* Support constructing let blocks with patterns

* Fix warning

* Review comments

* WIP

* WIP

* Fix typechecking

* Add lsp tests

* Add an error for duplicate bindings in a let block

* Update the manual

* Delete the old pattern file.

* Move test to integration
2024-09-10 15:06:07 +00:00
Nathan Pollart
273ae0f489
Add record constructor to subtyping (#2007)
* Initial draft without Constant and TailVar

* Restrict visibility of RemoveErrorRow to super

* Create trait Subsume for UnifType and UnifRecordRows

* Fix problem about {a: Type}<: {a:Type;b:Type} that was not accepted

* Copy comments (general comment on subsumption and closing a record when there is a record/dictionary subsumption)

* Fix problem (it was error reporting...)

* Rename trait

Co-authored-by: Yann Hamdaoui <yann.hamdaoui@gmail.com>

* Correct spelling in comments

Co-authored-by: Yann Hamdaoui <yann.hamdaoui@gmail.com>

* Rename trait impl

* Rename trait

* Update comments

* Remove subsumption function from typecheck/mod.rs

* Add test

* Add documentation

* Rename trait (for clippy)

* Add tests

* Modify snapshot lsp

* Update comments core/src/typecheck/subtyping.rs

Co-authored-by: Yann Hamdaoui <yann.hamdaoui@gmail.com>

* Update doc/manual/typing.md

Co-authored-by: Yann Hamdaoui <yann.hamdaoui@gmail.com>

* Modify comment

* Modify comment

* Revert lsp snapshot

* Cosmetic improvements

This commit performs minor cosmetic improvements in the code handling
subtyping, mostly around comments and function interfaces.

* Update snapshot test for LSP

The support of subtyping for record types makes some types to be
instantiated earlier than before. Given the way terms are visited, when
writing something like `let f = std.array.map in ..`, `std.array.map`
used to be inferred to be of a polymorphic type `forall a b. ...` and
then only was instantiated (because record access is inferred, while the
bound expression is checked). With the new implementation, it is
instantiated as part of the subsumption rule, meaning that it'll appear
differently on the LSP.

All in all, both version of the data shown by the LSP (before this
change and after) are meaningful, in some sense. The polymorphic type is
still shown when it's part of the metadata anyway, in addition to the
inferred monomorphic type. This also doesn't change which expressions
are accepted or not. It's more of an artifact of when we visit terms,
before or after instantiation and how those visits are intertwined with
`check` and `infer`. It's not easy to revert to the previous state of
affairs, and it's in fact not necessarily a good thing either: in the
example above, the LSP would also show a polymorphic type for `f` - the
one of `map` - while in fact `f` has a monomorphic type, so you couldn't
use it in different contexts (say on an `Array Number` and later on a
`Array String`). The current version is showing the real monomorphic
nature of `f`.

---------

Co-authored-by: Yann Hamdaoui <yann.hamdaoui@gmail.com>
Co-authored-by: Yann Hamdaoui <yann.hamdaoui@tweag.io>
2024-09-06 15:38:18 +00:00
dependabot[bot]
44aef1672a
chore(deps): bump micromatch in /lsp/vscode-extension (#2030)
Bumps [micromatch](https://github.com/micromatch/micromatch) from 4.0.5 to 4.0.8.
- [Release notes](https://github.com/micromatch/micromatch/releases)
- [Changelog](https://github.com/micromatch/micromatch/blob/master/CHANGELOG.md)
- [Commits](https://github.com/micromatch/micromatch/compare/4.0.5...4.0.8)

---
updated-dependencies:
- dependency-name: micromatch
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-09-04 12:34:47 +00:00
cydparser
165eeddcca
Fix windows tests (#2025)
* Fix benchmarks on Windows

* Fix tests for Windows

+ Improve failure messages

* Add CI job for Windows

* Disable unused warning for ParseFormatError

* Add `pprof` feature to utils
2024-08-09 01:26:23 +00:00
Yann Hamdaoui
b3c8e30b68
[Optimization] Cache contract generation and pre-compile some match expression (#2013)
* Pre-generate contracts

After the introduction of a proper node for types in the AST, we
switched to a lazy way of generating contract: we keep the type as it
is, and convert it to a contract only once it's actually applied. While
simpler, this approach has the drawback of potentially wasting
computations by running the contract generation code many times for the
same contract, as some metrics showed (up to 1.6 thousand times on large
codebases).

This commit add a `contract` field to `Term::Type`, and statically
generates - in the parser - the contract corresponding to a type. This
is what we used to do before the introduction of a type node. Doing so,
we only generate at most one contract per user annotation, regardless of
how many times the contract is applied at runtime.

* Pre-compile match in enum contract

This commit saves some re-compilation of the match expression generated
by contracts converted from enum types by generating the compiled
version directly instead of a match.

* Fix unused import warnings
2024-08-02 06:36:42 +00:00
jneem
935519f1ae
More aggressive type/contract deduplication on hover (#1984)
* More aggressive deduplication on hover.

Deduplicate not just the type annotations, but also the contract
annotations. Also, try to report Dyn less often.

* Add hover metadata for the field of a record.

* Review comments

* Add a comment
2024-07-03 18:56:20 +00:00
Théophane Hufschmitt
32a4b675a4
Make the LSP configurable (#1974)
* Make the LSP options configurable

Take into account the configuration sent by the client through
[`InitializeParams.initializationOptions`](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#initializeParams).

This is currently used to set the limits for the background evaluation,
although it also creates the infrastructure for setting more things.

* Fix the doc comments for the config

* Remove a useless explicit Default instance

Replace it by the derived one (thanks clippy)

* Comment fixes

Co-Authored-By: Yann Hamdaoui <yann.hamdaoui@tweag.io>

* Simplify the nls config definition

`#[serde(default)]` applied to a whole struct is enough for it to do the
right thing with the `Default` trait. Makes the module significantly
nicer to read.

---------

Co-authored-by: Yann Hamdaoui <yann.hamdaoui@tweag.io>
2024-07-02 19:24:30 +00:00
Théophane Hufschmitt
e2e6742c5a
Don't blacklist files forever in the lsp (#1973)
When the evaluator in the LSP times out or overflows its stack, the
faulty file is blacklisted so that it doesn't get evaluated any more.
This blacklist used to be permanent, which is generally not desirable
since it makes the LSP unusable.

Change that to only blacklist the file for a fixed delay currently
(hardcoded at 30s).
2024-06-21 17:01:19 +00:00
jneem
f5b5876baf
Combine metadata for completion items instead of choosing arbitrarily. (#1940)
* Combine metadata for completion items instead of choosing arbitrarily.

* Separate env completion from record field completion

* Update lsp/nls/src/requests/completion.rs

Co-authored-by: Yann Hamdaoui <yann.hamdaoui@tweag.io>

* Refactor remove_duplicates_and_myself

* Add test

---------

Co-authored-by: Yann Hamdaoui <yann.hamdaoui@tweag.io>
2024-06-18 19:34:45 +00:00
Yann Hamdaoui
808b268f29
Add span information for TOML imports (#1949)
This commits use a feature of the toml crate allowing to embed span
information into the deserialized data (imported from Nickel). This
makes it possible to give nice error messages and point to within a TOML
file when the application of a Nickel contract to an existing TOML
configuration fails, or in case of unmergeable values.

Doing so requires a bit of boilerplate and brings an additional crate in
(although small). It can also impact deserialization performance,
because we need to first deserialize in an intermediate TOML-like
datastructure. For those reasons, spanned deserialization has been gated
by the `spanned-deser` feature, which is enabled by default, but can be
disabled if this isn't useful.
2024-06-12 08:12:39 +00:00
dependabot[bot]
2a5ca51a63
chore(deps): bump braces from 3.0.2 to 3.0.3 in /lsp/vscode-extension (#1953)
Bumps [braces](https://github.com/micromatch/braces) from 3.0.2 to 3.0.3.
- [Changelog](https://github.com/micromatch/braces/blob/master/CHANGELOG.md)
- [Commits](https://github.com/micromatch/braces/compare/3.0.2...3.0.3)

---
updated-dependencies:
- dependency-name: braces
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-06-11 15:07:37 +00:00
jneem
9fe8b981f7
Update dependencies in the background evaluator (#1948)
The background evaluator needs to track dependencies separately, because
it doesn't share file ids with the main cache. This updates the
background dependencies when the foreground ones get updated.
2024-06-10 16:41:36 +00:00
jneem
446128b567
Fix nls crash, and better refresh diagnostics. (#1944)
* Add a test

* Invalidate cached terms.

In nls, if `main.ncl` imports `dep.ncl` and `dep.ncl` changes, we need
to invalidate some cached data about `main.ncl` and re-check it.
Previously we were simply resetting `main.ncl` to the "parsed" state in
the cache, but this isn't sufficient because our cached term for
`main.ncl` might depend on `dep.ncl`. Specifically, import resolution of
`main.ncl` transforms the term in a way that depends on whether
`dep.ncl` parsed.

This commit does the most inefficient (but easiest to get correct)
thing: throwing out all the parsed data and re-parsing from scratch.
This can be optimized, but it probably isn't too much slower than the
status quo, because we were re-typechecking from scratch anyway.

* Re-do background evaluation for invalidated files.

When `main.ncl` imports `dep.ncl` and `dep.ncl` changes, we invalidate
`main.ncl` and re-do some checks. This commit adds background
invalidation to the list of checks that we re-do.

* Move the recursive invalidation into Cache

* Reinstate/reword comment
2024-06-10 14:28:53 +00:00
Yann Hamdaoui
4c29726b98
Rename and re-organize primitive operators (#1937)
Primitive operators haven't got much love, as opposed to user-facing
interfaces like the stdlib, and they have grown organically since the
beginning of the very first Nickel prototype. As a result, the naming is
inconsistent, with several generations, both in the surface syntax of
Nickel and internally in the Rust codebase.

This PR makes a cleaning pass on primitive operators, by:

1. Use full worlds in the style of the current stdlib: `str` ->
   `string`, `num` -> `number`, etc.
2. Introduce pseudo-namespaces: instead of `str_foo` and `record_bar`,
   we use `/` as a separator for categories. The previous examples
   become `string/foo` and `record/bar`. We don't use `.`, to make it
   clear that it's not a normal record access, but just a nice way to
   dinstinguish the different categories
3. Align old operators on the current naming in the standard library.
2024-06-07 11:27:21 +00:00
Erin van der Veen
3b00223521
use Topiary's published crates over git (#1919)
Now that Topiary is published and crates.io (and tree-sitter-nickel as
well), we move away from git revision and use proper public versions for
those. Doing so, we can also crap the special casing that was done
during release to disable those dependencies and we'll now be able to
release on crates.io a version with formatting enabled.

Co-authored-by: Yann Hamdaoui <yann.hamdaoui@tweag.io>
2024-06-06 16:58:44 +00:00
Yann Hamdaoui
d4d864d25e
Add --version support to NLS, fix feature unif (#1936)
Add `--version` support for the nls binary, using the same scheme as for
the main `nickel` binary.

Doing so, we discovered some underlying feature unification issues that
weren't visible before - but were already there -, namely that the
little stunt we pull off for generating versions in different
environment (in the git repo, building for crates.io and the nixified
version) requires the `string` feature of clap. It just happened that it
was enabled previously for `nickel-lang-cli` by chance by feature
unification (through `comrak`), but in fact building `nickel-lang-cli`
without the default features was failing.

This commit fixes the compilation issue by adding the missing `string`
feature to the `clap` dependency for both the cli and the lsp.
`nickel-lang-lsp` also depends on `nickel-lang-core` without the default
features now (as most of them are useless for the LSP), and we fix the
another compilation error of `nickel-lang-cli` without default features
by making `nickel-lang-core` always export `eval_record_spine`, which
would only be included when the `doc` feature was enabled before, but is
actually used for other purposes now (namely the CLI customize mode).
2024-06-03 14:59:26 +00:00
jneem
b14aeea035
Tell lsp about variable bindings in match statements (#1926)
* Tell lsp about variable bindings in match statements

* Also handle unapplied matches

* insta review

* Add a test getting match branch completions from type inference
2024-05-27 03:08:19 +00:00
Yann Hamdaoui
ca0f78fdbf
Or patterns (#1916)
This commit introduces or-patterns, which allows to express alternatives
within patterns, including in a deep subpattern.

The compilation of or-patterns is rather simple: we simply try each
alternative until one matches, and use the corresponding bindings.

Typechecking of or-patterns can be done following the same process as
for typechecking a whole match expression (which is also a disjunction
of patterns), although the treatment of bound variables is a bit
different.

Most of the complexity of this commit comes from the fact that we don't
want to make `or` a reserved language keyword, which would break
backward compatibility. This is possible, because `or` in pattern can't
be confused with an identifier, but it requires some tweaking to make
our LALR(1) parser accept this.
2024-05-25 12:25:58 +00:00
Yann Hamdaoui
3af21b0d08
Implement array patterns (#1912)
This commit adds a new calss of patterns: array patterns. This is a
natural extension, both syntactically and semantically, of existing data
structure patterns in Nickel (in particular of records). Similarly,
arrays pattern can also capture the rest of the pattern (the tail of the
array that hasn't been matched yet) and bind it to a variable.
2024-05-16 15:29:30 +00:00
Yann Hamdaoui
7225b729c2
Implement pattern guards (#1910)
* Implement pattern guards

This commit implement pattern guards, which are side conditions that can
be added to the branch of a match expression, following the pattern, to
further constrain the matching. This condition is introduced by the
(already existing) `if` keyword. For example:

`match { {list} if list != [] => body }` will match a record with a
unique field `list` that isn't empty.

The compilation is rather straightforward, as a pattern is already
compiled to a tree of if-then-else while also building the bindings
introduced by pattern variables. After all the conditions coming from
the pattern have been tested, we just additionally check for the guard
(injecting the bindings in the condition since the guard can - and most
often does - use variables bound by the pattern).

* Update core/src/term/mod.rs

Co-authored-by: jneem <joeneeman@gmail.com>

* Exclude guarded patterns from tag-only optimization

---------

Co-authored-by: jneem <joeneeman@gmail.com>
2024-05-13 15:29:37 +00:00
Jakub A. G
aca39eff18
Allow other formats for singleton input (#1901) (#1902)
Guess input format based on extension similarly like in multiple input case.
2024-05-07 08:33:28 +00:00
Yann Hamdaoui
07cd7197e1
Uniformize destruct and pattern matching logic (#1907)
* Uniformize destruct and pattern matching logic

When patterns were first introduced, only let-destructuring existed, and
match expressions weren't a thing. Rather than to manually generate code
that would check that a pattern does match the destructured value, we
piggy-backed on contracts instead, which was easier and provided better
error messages. Up to now, this was still how destructuring worked: a
contract is elaborated from the pattern and applied to the matched
value, and should report any error if the value doesn't match. Then,
destructuring is desugared to a series of let-bindings that assume that
the destucture value has the right shape. The generated code is thus
quite simple, as it doesn't have any error handling to do.

When pattern matching landed, we kept the old destructuring
infrastructure, because it was there and worked well. However, there is
duplication: the compilation of match expressions does a work quite
similar to destructuring.

What's more, we're at risk of having a diverging semantics. Some
questions aren't trivial to answer for destructuring, in particular with
respect to lazyness: should `let _ = x in null` force `x`? What about
`let 'Foo _ = x in null`, or `let 'Foo 5 = x in null`?

After some discussion, we decided to give destructuring a simple
semantics in term of pattern matching: `let <pat> = <matched> in <body>`
should be strictly equivalent to `<matched> |> match { <pat> => <body>
}`. Indeed, `match` has a clear semantics around forcing values in lazy
languages. This also agrees with intuition, or at least gives a
reasonable semantics for most cases.

This commit implements this change in practice, by getting rid of the
ad-hoc desugaring of destructuring and rewriting let-destructuring to
actual pattern matching instead.

* Update core/src/term/pattern/compile.rs

Co-authored-by: jneem <joeneeman@gmail.com>

---------

Co-authored-by: jneem <joeneeman@gmail.com>
2024-05-06 16:06:46 +00:00
Yann Hamdaoui
e8e9a346b2
Wildcard patterns (#1904)
* Add wildcard patterns

This commit adds a special pattern that doesn't bind anything and match
any value, the wildcard pattern `_`. This pattern doesn't force the
value being matched on.

* Update core/src/typecheck/pattern.rs

Co-authored-by: jneem <joeneeman@gmail.com>

* Fix mishandling of wildcard in enum pattern match compilation

---------

Co-authored-by: jneem <joeneeman@gmail.com>
2024-05-06 04:09:57 +00:00
Yann Hamdaoui
3b01e62864
Add support for constant pattern (#1897)
This commit adds support for constant patterns, that is patterns
matching specific booleans, strings, numbers or the null value.
2024-05-02 08:43:46 +00:00
Yann Hamdaoui
b731a436a7
Fix LSP not showing types in untyped code (#1889)
Most of the time, hovering over a symbol in untyped code would show
`Dyn` even though the symbol has a type annotation - in particular for
records accessed via a non-trivial path, e.g. `foo.bar.baz`. This is an
issue because in particular, we don't get to see the right types for
stdlib symbols when hovering over them.

This commit fixes the issue by taking the type annotation instead of the
type provided by the typechecker when the latter is `Dyn`.
2024-04-12 16:48:24 +00:00
Yann Hamdaoui
63edc969e2
Leverage function contract information (#1888)
When a function is annotated with a function contract, use this
additional type information to enable completion in the LSP (and also
use the domain as the type of the function's argument in the typing
environment, even if we are in walk mode). Contract data are easy to
fetch during typechecking when available and use them improve the
developer experience by bringing in more static information.
2024-04-12 16:43:31 +00:00
jneem
34a99fd55a
Extend the symbol range to include the rhs (#1887)
* Extend the symbol range to include the rhs

* Review comments
2024-04-11 22:18:45 +00:00
jneem
1f40fcfb0f
Dedup diagnostics (#1883)
* Deduplicate diagnostics

* Test the diagnostics deduplication
2024-04-05 19:19:00 +00:00
jneem
262ac8fa36
Fix infinite recursion in doc symbols. (#1881) 2024-04-04 08:57:19 +00:00
jneem
cb91eeb71f
Add a recursion limit to background evaluation (#1878)
* Add a recursion limit to eval_permissive

* Add a test

* Review comments
2024-03-29 18:35:54 +00:00
jneem
1caa77e0d8
Don't leak memory in background eval (#1869)
* Run a separate process for each background evaluation job

* Send over only the dependencies, not everything

* Remove ipc-channel

* Kill the child process if it times out

* Add some comments
2024-03-26 20:12:37 +00:00
jneem
e5bdef661f
Improve diagnostic location in nls (#1856)
* Improve diagnostic location

* insta review
2024-03-15 17:48:01 +00:00
jneem
342655cb95
Fix a flaky test (#1858) 2024-03-15 17:44:09 +00:00
jneem
a4a9d6a2c6
Propagate pending array contracts (#1854) 2024-03-14 21:24:59 +00:00
Yann Hamdaoui
2c5b8f1f07
1.5.0 release (#1853)
* [release.sh] update to 1.5.0

* Fix LSP not compiling when format feat is disabled

* Add 1.5 release notes

* Don't mention current release in the manual intro

We used to mention the current release version in the manual intro, but
this is tedious to keep in sync, and not very valuable - this
information is really easy to get by many other mean. The original
intent was to insist that Nickel was past 1.0, and thus was considered
relatively stable and usable in production. The text has been reworded
to say that instead.
2024-03-13 14:54:30 +00:00
jneem
9988d52352
Reinstate notes in in-editor diagnostics (#1851) 2024-03-12 16:37:53 +00:00
jneem
5eaff39907
Remove some spurious diagnostics from background eval (#1847)
* Remove some spurious diagnostics from background eval

* Reset it better
2024-03-12 14:58:39 +00:00
jneem
b54ae16c31
Improve document symbols (#1848) 2024-03-12 14:34:58 +00:00
jneem
283d0721e8
LSP evaluation in the background (#1814)
* Initial version of background eval

Doesn't support termination, which is probably not good enough

* Kill misbehaving workers

* Clean up the diagnostics

* Improve diagnostics and factor out World from Server

* Fix mistaken ranges for cross-file diagnostics

* Stray dbg

* Fix panic

* Fix rebase issues

* Remove some spurious diagnostics

* Fix link

* Workspace dependencies

* Code review comments

* Add a test

* Issue multiple diagnostics, and ignore partial configurations

* Move eval_permissive to VirtualMachine
2024-03-08 19:27:44 +00:00
Yann Hamdaoui
0cc6496f70
Fix the semantics of default values in patterns (#1826)
* Fix semantics of default values in patterns

The previous semantics of default value in patterns (set with the `?`
annotation) were kinda accidental: at the time they were introduced, it
was much easier to implement default values by the `default` merge
priority. However, it's not aligned with intuition when using default
value in match statement or function argument patterns: the goal here is
mostly to say, if the field isn't defined, I want to use fallback value.
The previous implementation, for example, could fail with merge conflict
or happily merge two default values. In fact, we want to give the
priority to any value that exists in the matched value, whatever is its
actual merge priority.

This commit implements the desired semantics: pattern default values are
only set if the field isn't there, or is there but has no definition. In
that case, we rely on merging to avoid erasing any metadata present
previously (for example, if we set a default value in `{foo | String}`,
we don't want to drop the `String` contract, so we can't use
std.record.update blindly).

* Add From<_> instances to ease Field creation
2024-02-21 11:41:25 +00:00
Yann Hamdaoui
6f38f16e6f
Full pattern matching (#1820)
* Extend match expressions to full patterns

This commit brings together many previous chunks of work to finally make
match expressions accept generic patterns, and not just enum tags.

Pattern compilation was already implemented. Besides changing the
parsing rule for "match" and change the implementation to compile the
pattern and applies the result to the argument, the bulk of the work has
been to correctly typecheck arbitrary structural patterns.

Refer to the comments for the "Match" case in the typechecker for more
details about the algorithm.

* Fix failing test, reword code documentation

* Fix undue unbound identifier when typechecking match

* Add tests for full pattern matching

* Fix null error in pattern compilation

The compilation of record pattern was missing a null check which would
trigger a dynamic type error when some matches aren't exhaustive. This
commit fixes the issue by adding the missing null check.

* Fix clippy warnings

* Limited rewording of some code comments

* Post-rebase fixup of snapshot tests

* Apply suggestions from code review

Co-authored-by: Viktor Kleen <viktor.kleen@tweag.io>

---------

Co-authored-by: Viktor Kleen <viktor.kleen@tweag.io>
2024-02-19 16:44:30 +00:00
Yann Hamdaoui
0768f05210
Enum tag destructuring (#1813)
* Support enum tags in patterns

Until now, only enum variants were supported within patterns (applied
enums). This commit adds support for bare enum tags as well.

* Improve enum variants handling in stdlib

Make `typeof` returns `'Enum` for enum variants as well, and update
`std.contract.Equal` to properly handle enum tags and enum variants.

* Add tests for enum tag patterns

* Update manual's sample to make tests pass
2024-02-13 10:54:40 +00:00
Yann Hamdaoui
b01f9b89f1
ADT destructuring (#1812)
* Add unwrap_enum_tag primop

Add a primitive operation to extract the argument from an enum variant,
which will prove useful to enum matching and destructuring.

* Add get_tag and is_variant enum primops

* ADTs destructuring

This commit adds support for enum variant patterns in destructuring
forms (let bindings and function declarations). This paves the way for
matching on ADTs once we allow patterns not only appear in a
destructuring binding, but also in a match expression.

* Make get_tag work on simple enum tags as well

* Fix pretty printing of enum_unwrap_variant

* Additional tests for ADTs destructuring

* Fix unification order

A test revelead that the typechecking errors were off sometimes for
destructuring lets: if the destructured value didn't correspond to the
pattern, the type elaborated from the pattern appeared as the inferred
type of the expression, and the inferred type of the expression as the
expected type (i.e. the two were reversed).

This causes incorrect error messages like "extra row" instead of
"missing row". This commits fix the issue by unifying the type deduced
from the pattern and the type inferred from the bound expression in the
right order (unification is symmetric, as far as typechecking is
concerned, but for error reporting we do distinguish between expected
and inferred type).

* Fix type of is_variant to not break parametricity

* Remove useless TODO: tests will catch this

* Format stdlib internals
2024-02-09 17:24:49 +00:00
jneem
839a118212
Rename LSP action (#1811)
* Add rename support

(Cross-file renaming is only working in one direction)

* Fix some rebase issues

* Insta review

* Make the test deterministic
2024-02-09 16:59:51 +00:00
Yann Hamdaoui
b57f74bef3
[Refactor] Pattern matching (#1799)
* Refactoring of pattern destructuring

This commit is a preliminary work for the upcoming ADTs (and more
generally the introduction of pattern matching, instead of just having
destructuring).

The refactoring aims at installing a consistent naming, simplify the
representation of patterns and their associated method, and pave the way
for other patterns that just records. Indeed, the previous
implementation often made the implicit assumptions that patterns were
only record patterns.

* Avoid illegal state for record patterns

Record pattern was previously using a tuple `(open: bool, rest:
Option<LocIdent>)` to represent the presence of either no tail, an
non-capturing tail `..`, or a capturing tail `..rest`. This
representation allows the illegal state `(false, Some("x"))`: indeed, if
the tail is capturing, the record contract is necessarily open.

This commit flattens this representation to a single enum that correctly
represents those three different cases, instead of the 4 allowed by the
previous representation.

* Move the alias field to Pattern

The AST of patterns had a special node for an aliased pattern, which was
a variant containing the alias and a potentital nested pattern. However,
this doesn't model correctly patterns: usually, it doesn't make sense to
stack aliases (and the parser won't accept it), but the previous
representation accepted ASTs for things like `x @ y @ z @ <pat>`, which
incurs additional burden to handle, although it can actually never
happen.

Additionally, the alias of the top pattern was duplicated as an optional
field in the `LetPattern` and `FunPattern` nodes of the `Term` AST.

This commit makes things simpler by storing `alias` as an optional field
directly in the `Pattern` struct, which makes it accessible without
having to pattern match on an enum variant, and forbids nested aliases.
Doing so, we remove the duplication from the `LetPattern` and
`FunPattern`, which now only takes a pattern instead of an optional
identifier and a pattern, leading to code simplification.

* Restore old behavior in typed patterns

The refactoring of patterns has introduced a slightly different
algorithm for typechecking patterns, which isn't entirely
backward-compatible, although it's more consistent. We'll probably rule
out (i.e. depreacte) the offending special cases, but until then, this
commit restores the previous behavior, which fixes a previously failing
test.

* Various renamings in destructuring (now pattern)

This commit only applies pure renaming of several symbols of the
destructuring module for improved clarity. The whole module is also
moved to `term::pattern`, as patterns are just syntactic component of
the term AST.

* Apply suggestions from code review

Co-authored-by: Viktor Kleen <viktor.kleen@tweag.io>

* Post-rebase fixup

---------

Co-authored-by: Viktor Kleen <viktor.kleen@tweag.io>
2024-02-09 14:42:32 +00:00
jneem
ec776e526f
Improved (but possibly expensive) reference-finding (#1800)
* Refactor get_defs

* Improve reference-finding to find more static-accesses

* comment

* Add a benchmark
2024-02-08 16:18:45 +00:00