Commit graph

32 commits

Author SHA1 Message Date
Vincent Ambo
f8919dbcd6 fix(tvix/eval): address current clippy lints
Note that I've allowed `needless_lifetimes` for the attribute set
iterator, as I find the type easier to understand with these
annotations present.

Change-Id: I33abb17837ee4813076cdb9a87f54bac4a37044e
Reviewed-on: https://cl.tvl.fyi/c/depot/+/6373
Reviewed-by: sterni <sternenseemann@systemli.org>
Tested-by: BuildkiteCI
2022-09-07 19:08:56 +00:00
Vincent Ambo
38d3db5fb8 feat(tvix/eval): implement NixAttrs::iter()
Implementing iteration over NixAttrs requires a custom iterator type
in order to encapsulate the different representations. The BTreeMap
for example has its own iterator type which needs to be encapsulated.

This is mostly boilerplate code, but for a change some simple unit
tests have been added in.

Change-Id: Ie13b063241d461b810876f95f53878388e918ef2
Reviewed-on: https://cl.tvl.fyi/c/depot/+/6367
Tested-by: BuildkiteCI
Reviewed-by: sterni <sternenseemann@systemli.org>
2022-09-07 15:25:59 +00:00
Vincent Ambo
3a2fcc8bc2 refactor(tvix/eval): avoid cloning in NixAttrs::update if possible
Refactors the update function to take the attribute sets by value
instead.

To facilitate this, we use an equivalent of the currently unstable
`Rc::clone_or_unwrap` in the VM when encountering attribute sets, so
that in cases where the only references to the attrs being updated are
the ones on the stack those clones are avoided completely.

This does make update() a little bit more tricky internally, as some
optimised branches can directly return the moved value, and others
need to destructure with ownership. For this reason there are now two
different match statements handling the different ownership cases.

Change-Id: Ia77d3ba5c86afb75b9f1f51758bda61729ba5aab
Reviewed-on: https://cl.tvl.fyi/c/depot/+/6279
Tested-by: BuildkiteCI
Reviewed-by: sterni <sternenseemann@systemli.org>
2022-09-03 13:19:48 +00:00
Vincent Ambo
48b0fac76b refactor(tvix/eval): slightly more readable AttrsRep::select
Suggestion from grfn in cl/6158.

Change-Id: I16dcf2296a5ec5d299d5a080ca099b8eda6c254e
Reviewed-on: https://cl.tvl.fyi/c/depot/+/6278
Reviewed-by: grfn <grfn@gws.fyi>
Tested-by: BuildkiteCI
2022-09-03 00:49:45 +00:00
Vincent Ambo
bc9351f811 refactor(tvix/eval): get rid of Value::Blackhole variant
This is no longer needed for anything and the extra clone here is not
really more costly than constructing a blackhole value in a different
place.

Change-Id: I5c63085b1b4418b629ea58a42e3bfe9a9b586d76
Reviewed-on: https://cl.tvl.fyi/c/depot/+/6275
Reviewed-by: grfn <grfn@gws.fyi>
Tested-by: BuildkiteCI
2022-09-03 00:49:45 +00:00
Vincent Ambo
edee8eecdf fix(tvix/eval): address all current clippy lints
Change-Id: I758fc4f3b9078de7ca6228a75a4351c3e085c4cf
Reviewed-on: https://cl.tvl.fyi/c/depot/+/6272
Reviewed-by: grfn <grfn@gws.fyi>
Tested-by: BuildkiteCI
2022-09-03 00:47:58 +00:00
Vincent Ambo
1416f1ab8a refactor(tvix/eval): avoid a use of Value::Blackhole
The blackhole allocation is not going to be cheaper than cloning this.

Change-Id: Id3ad44812decb4392830be06645e67bb0a982b96
Reviewed-on: https://cl.tvl.fyi/c/depot/+/6267
Reviewed-by: grfn <grfn@gws.fyi>
Tested-by: BuildkiteCI
2022-09-02 15:45:43 +00:00
Vincent Ambo
c3b13416b0 refactor(tvix/eval): add NixAttrs::contains function
This avoids copying around the value more than needed.

Change-Id: I35949d16dad7fb8f76e0f641eaccf48322144777
Reviewed-on: https://cl.tvl.fyi/c/depot/+/6263
Tested-by: BuildkiteCI
Reviewed-by: sterni <sternenseemann@systemli.org>
2022-09-02 13:36:48 +00:00
Vincent Ambo
3d0280ec03 refactor(tvix/eval): implement clearer mechanism for globals
The set of things that can leak out of `builtins` into the global
scope is statically known (it is what Nix 2.3 leaks there,
essentially).

This is a mild change over the previous mechanism, where instead at
the point where the `builtins` set is constructed we "lift" the
globals out of there (if they exist).

This way users will still eventually be able to add additional
builtins, HOWEVER they will not be able to leak them into the global
scope.

Note that upstream Nix technically leaks _all_ builtins into the
global scope using the `__*` prefix, but we are trying to avoid this
in Tvix if it is not required in nixpkgs.

Change-Id: Ie9dec2ce33740134f3b2464eba3749f421dd5953
Reviewed-on: https://cl.tvl.fyi/c/depot/+/6258
Tested-by: BuildkiteCI
Reviewed-by: sterni <sternenseemann@systemli.org>
2022-09-02 12:59:23 +00:00
Vincent Ambo
2662376941 feat(tvix/eval): carry optional SyntaxNode in error type
This starts paving the way for nicer, source-code based error
reporting.

Right now the code paths in the VM do not emit annotated errors, as we
do not yet preserve that structure from the compiler. However, error
emitting code paths in the compiler have been amended to include known
nodes.

Change-Id: I1b74410ffd891c40cd913361bd73c4336ec8aa5b
Reviewed-on: https://cl.tvl.fyi/c/depot/+/6235
Tested-by: BuildkiteCI
Reviewed-by: grfn <grfn@gws.fyi>
2022-09-01 21:40:50 +00:00
Vincent Ambo
43658a5b90 fix(tvix/eval): emit correct count in OpAttrPath
Not sure how exactly this snuck in, but it caused some subtle
breakages in deeply nested attribute sets.

Change-Id: I8049ce912405d3750031f79cc8d86ff1c3c02c2b
Reviewed-on: https://cl.tvl.fyi/c/depot/+/6208
Reviewed-by: grfn <grfn@gws.fyi>
Tested-by: BuildkiteCI
2022-08-30 17:13:27 +00:00
Vincent Ambo
8d45fbadea docs(tvix/eval): Use correct syntax for module doc comments
Change-Id: I35741856f34b86a538f226a8eaf8806edede60ec
Reviewed-on: https://cl.tvl.fyi/c/depot/+/6207
Reviewed-by: grfn <grfn@gws.fyi>
Tested-by: BuildkiteCI
2022-08-30 17:13:27 +00:00
Vincent Ambo
11ea7b82d8 chore(tvix/eval): minor readability improvement in attrs
Change-Id: If9d9eaf60934e96ec4b41c57818afe0c2a99c862
Reviewed-on: https://cl.tvl.fyi/c/depot/+/6206
Reviewed-by: grfn <grfn@gws.fyi>
Reviewed-by: sterni <sternenseemann@systemli.org>
Tested-by: BuildkiteCI
2022-08-30 17:13:27 +00:00
Vincent Ambo
de26894814 refactor(tvix/eval): remove Error::InvalidKeyType
We're confident that we're handling all branches that can reasonably
occur from valid AST, any other cases should be considered a critical
evaluator bug and panic rather than surfacing something that looks
like user error.

Change-Id: If96966eb32b8ff12fcaeb9ea3b0c8fc51b6abd11
Reviewed-on: https://cl.tvl.fyi/c/depot/+/6205
Reviewed-by: grfn <grfn@gws.fyi>
Tested-by: BuildkiteCI
2022-08-30 17:13:27 +00:00
Vincent Ambo
ab9407bded fix(tvix/eval): address various clippy lints
Change-Id: I3ea0f51475e80948adfeb5d1620c1f2665cc39bc
Reviewed-on: https://cl.tvl.fyi/c/depot/+/6201
Tested-by: BuildkiteCI
Reviewed-by: sterni <sternenseemann@systemli.org>
2022-08-30 16:53:40 +00:00
Vincent Ambo
c4f73eecdc feat(tvix/eval): implement attribute set equality
Change-Id: Ia25f02610f2575e5e7fca81643e05b40f4a07820
Reviewed-on: https://cl.tvl.fyi/c/depot/+/6200
Reviewed-by: sterni <sternenseemann@systemli.org>
Tested-by: BuildkiteCI
2022-08-30 16:53:40 +00:00
Vincent Ambo
2ea71aa4c3 fix(tvix/eval): null in dynamic attribute keys skips the element
This is actually *tested* behaviour in C++ Nix, so we need to
implement it here, too.

Change-Id: Ic4a4659a2f04cdd928cbe78a85dae90401515371
Reviewed-on: https://cl.tvl.fyi/c/depot/+/6199
Reviewed-by: sterni <sternenseemann@systemli.org>
Tested-by: BuildkiteCI
2022-08-30 16:53:40 +00:00
Vincent Ambo
1d86c4537e refactor(tvix/eval): use write! macro instead of f.write_fmt
grfn pointed out in cl/6082 that this is actually the desugaring of
the write! macro, so it doesn't make sense to  write it out.

Change-Id: If7c055b042ad22b034722aec1eaadba92736d684
Reviewed-on: https://cl.tvl.fyi/c/depot/+/6180
Tested-by: BuildkiteCI
Reviewed-by: sterni <sternenseemann@systemli.org>
Reviewed-by: grfn <grfn@gws.fyi>
2022-08-27 09:27:13 +00:00
Vincent Ambo
4c9d3fa2a6 chore(tvix/eval): explicitly set #[repr(transparent)] on wrappers
For representation wrappers that are used to control the visibility of
type internals, this ensures that the wrapper does not increase the
size of the type.

In practice, the optimiser likely does this anyways but it is good to
guarantee it.

Change-Id: Ic6df7d668fe6006dfbd5b6cfcfc2088afa95b810
Reviewed-on: https://cl.tvl.fyi/c/depot/+/6178
Tested-by: BuildkiteCI
Reviewed-by: grfn <grfn@gws.fyi>
2022-08-27 09:27:13 +00:00
Vincent Ambo
999b9c7a13 refactor(tvix/value): replace static representation with SmolStr
The only uses of the static variant were for `"name"` and `"value"`,
which are both small enough to fit into a SmolStr. The size of
NixString accomodates `String` anyways, so we may as well inline them.

Additionally smol_str is already in the dependency graph because rnix
uses it, and using it for representations of identifiers is sensible.

Change-Id: I9969312256d1657d69128e54c47dc7294a18ce58
Reviewed-on: https://cl.tvl.fyi/c/depot/+/6165
Tested-by: BuildkiteCI
Reviewed-by: sterni <sternenseemann@systemli.org>
Reviewed-by: grfn <grfn@gws.fyi>
2022-08-26 15:06:52 +00:00
Vincent Ambo
20f5ccefeb feat(tvix/eval): implement attribute set access operator
Fairly straightforward, handling the optimised representations
manually and otherwise delegating to BTreeMap.

Note that parsing of raw identifiers is not yet implemented.

Encountering an identifier node usually means that there is locals
access going on, so we need a special case for compiling a node in
such a way that an identifier's literal value ends up on the stack.

Change-Id: I13fbab7ac657b17ef3f4c5859fe737c321890c8a
Reviewed-on: https://cl.tvl.fyi/c/depot/+/6158
Tested-by: BuildkiteCI
Reviewed-by: sterni <sternenseemann@systemli.org>
Reviewed-by: grfn <grfn@gws.fyi>
2022-08-26 09:02:38 +00:00
Vincent Ambo
a0cbc78a83 refactor(tvix/value): ensure internal attrs representation is hidden
Wraps the attrs representation in an additional newtype struct with a
private field in order to hide the representation from other modules.

This is done in order to avoid accidental leakage of the internals
outside of value::attrs.

Change-Id: I68d1d02514aa0443df4c39801001a3f1f6cc5d5c
Reviewed-on: https://cl.tvl.fyi/c/depot/+/6146
Tested-by: BuildkiteCI
Reviewed-by: sterni <sternenseemann@systemli.org>
2022-08-25 12:07:30 +00:00
Vincent Ambo
058e77bab2 feat(tvix/eval): implement attrset update (//) operator
The underlying implementation does a few tricks based on which pair of
attrset representations is encountered.

Particularly the effect of short-circuiting the empty cases might be
relevant in nixpkgs/NixOS, due to the use of lib.optionalAttrs.

Change-Id: I22b978b1c69af12926489a71087c6a6219c012f3
Reviewed-on: https://cl.tvl.fyi/c/depot/+/6140
Reviewed-by: sterni <sternenseemann@systemli.org>
Tested-by: BuildkiteCI
2022-08-25 11:34:00 +00:00
Vincent Ambo
3671056640 fix(tvix/value): align Display representation with Nix
Displaying the optimised representation is not useful anymore.

Change-Id: Icb962ff8865ec4207c144fbcb1aae87483b0fb7c
Reviewed-on: https://cl.tvl.fyi/c/depot/+/6131
Tested-by: BuildkiteCI
Reviewed-by: grfn <grfn@gws.fyi>
2022-08-24 23:11:12 +00:00
Vincent Ambo
5685f7c594 fix(tvix/value): add ident_str representation of strings
When printing strings as identifiers (in attribute sets), the string
should only be quoted and escaped if it contains escape characters.

Change-Id: If2bcfa1e93dc8f00be4d7a57ec1d82fc679103c3
Reviewed-on: https://cl.tvl.fyi/c/depot/+/6127
Tested-by: BuildkiteCI
Reviewed-by: grfn <grfn@gws.fyi>
Autosubmit: tazjin <tazjin@tvl.su>
2022-08-24 21:25:41 +00:00
Vincent Ambo
6dc9ca5723 feat(tvix/value): introduce string representation with &'static str
For cases where the strings are statically known (such as the
oft-occuring name/value), this can be a useful optimisation.

It's also much more convenient in tests.

Change-Id: Ie462b684805bd4986ea5e85ca4bff663bc2d3c3c
Reviewed-on: https://cl.tvl.fyi/c/depot/+/6111
Tested-by: BuildkiteCI
Reviewed-by: eta <tvl@eta.st>
2022-08-24 18:19:52 +00:00
Vincent Ambo
c7ba2dec04 test(tvix/value): add simple attrset construction tests
These do not yet test nested attribute sets; we need to add some more
inspection primitives first.

Change-Id: Icfc99bf17c73ebefc0d882a84f0ca73ec688a54d
Reviewed-on: https://cl.tvl.fyi/c/depot/+/6110
Reviewed-by: eta <tvl@eta.st>
Tested-by: BuildkiteCI
2022-08-24 18:19:52 +00:00
Vincent Ambo
08b4d65fbd feat(tvix/value): implement nested attribute set literals
With this change, nested attribute sets can now be created from
literals.

This required some logic for dealing with cases where at a deeper
nesting point a literal attribute set was constructed from an
optimised representation.

For example, this is valid Nix code:

```nix
{
  a = {};   # creates optimised empty representation
  a.b = 1;  # wants to add a `b = 1` to it

  b = { name = "foo"; value = "bar"; }; # creates optimised K/V repr
  b.foo = 42; # wants to add an additional `foo = 42`
}
```

In these cases, the attribute set must be coerced to a map
representation first which is achieved by the new internal
NixAttr::map_mut helper.

Change-Id: Ia61d3d9d14c4e0f5e207c00f6a2f4daa3265afb2
Reviewed-on: https://cl.tvl.fyi/c/depot/+/6109
Reviewed-by: eta <tvl@eta.st>
Tested-by: BuildkiteCI
2022-08-24 18:19:52 +00:00
Vincent Ambo
293fb0ef53 refactor(tvix/value): encapsulate attrset logic within value::attrs
The internal optimisations of the set representation were previously
leaking into the VM, which is highly undesirable.

Keeping it encapsulated allows us to do additional optimisations
within value::attrs without being concerned about its use in the VM.

Change-Id: I7e7020bb0983b9d355d3db747b049b2faa60131f
Reviewed-on: https://cl.tvl.fyi/c/depot/+/6108
Reviewed-by: eta <tvl@eta.st>
Tested-by: BuildkiteCI
2022-08-24 18:19:52 +00:00
Vincent Ambo
e876c3a41c fix(tvix/value): KV struct needs to carry name as Value, too
Users may construct a pair that falls into the name/value optimisation
but where `name` is not actually a string, as from the language
perspective there is nothing special about this attribute set.

We also can not conditionally apply this by forcing the key at this
point, as this would change the language semantics.

Therefore, the name in the optimised representation is also carried as
`Value`.

Change-Id: I5be8a4c98ba19ebdfb7203a929f714a04492512e
Reviewed-on: https://cl.tvl.fyi/c/depot/+/6101
Reviewed-by: grfn <grfn@gws.fyi>
Tested-by: BuildkiteCI
2022-08-13 20:24:12 +00:00
Vincent Ambo
2ed38a7cdb feat(tvix/eval): add Value variants for strings & attrsets
Change-Id: Idebf663ab7fde3955aae50f635320f7eb6c353e8
Reviewed-on: https://cl.tvl.fyi/c/depot/+/6087
Tested-by: BuildkiteCI
Reviewed-by: grfn <grfn@gws.fyi>
2022-08-13 11:50:37 +00:00
Vincent Ambo
ba03226e51 feat(tvix/eval): add module for attribute set implementations
Change-Id: I6002bd5e5596b93325dea6c862370ba5235c0f08
Reviewed-on: https://cl.tvl.fyi/c/depot/+/6086
Tested-by: BuildkiteCI
Reviewed-by: grfn <grfn@gws.fyi>
2022-08-13 11:50:37 +00:00