about summary refs log tree commit diff
path: root/tvix/eval/src/tests
AgeCommit message (Collapse)AuthorFilesLines
2022-09-15 r/4859 fix(tvix/eval): thunk string interpolationsterni2-0/+8
If we have multiple string parts, we need to thunk assembling the string. If we have a single literal, it is strict (like all literals), but a single interpolation part may compile to a thunk, depending on how the expression inside is compiled – we can avoid forcing to early here compared to the previous behavior. Note that this CL retains the bug that `"${x}"` is erroneously translated to `x`, implying e.g. `"${12}" == 12`. The use of `parts.len()` is unproblematic, since normalized_parts() builds a `Vec` instead of returning an iterator. Change-Id: I3aecbfefef65cc627b1b8a65be27cbaeada3582b Reviewed-on: https://cl.tvl.fyi/c/depot/+/6580 Autosubmit: sterni <sternenseemann@systemli.org> Reviewed-by: tazjin <tazjin@tvl.su> Tested-by: BuildkiteCI
2022-09-15 r/4857 feat(tvix/eval): implement correct toString behaviorsterni2-7/+24
Implement C++ Nix's `EvalState::coerceToString` minus some of the Path / store handling. This is currently only used for `toString` which does all possible coercions, but we've already prepared the weaker coercion variant which is e.g. used for builtins that expect string arguments. `EvalState::coerceToPath` is still missing for builtins that need a path, but it'll be easy to build on top of this. Change-Id: I78d15576b18921791d04b6b1e964b951fdef22c6 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6571 Autosubmit: sterni <sternenseemann@systemli.org> Reviewed-by: tazjin <tazjin@tvl.su> Tested-by: BuildkiteCI
2022-09-13 r/4849 fix(tvix/eval): force left argument of `?` before checking for attrssterni2-0/+27
OpAttrsIsSet and OpAttrsTrySelect will fail silently if the attribute set value on the stack is actually a thunk, so we need to make sure to force at every step of the way. Emitting the force instructions in the compiler because it is easier to add, but maybe the VM should do this when handling the relevant opcodes? Comments welcome. Change-Id: I65c5ef348d59b2d07c9bb06abb24f9f3e6a0fdb2 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6540 Reviewed-by: grfn <grfn@gws.fyi> Autosubmit: sterni <sternenseemann@systemli.org> Tested-by: BuildkiteCI Reviewed-by: tazjin <tazjin@tvl.su>
2022-09-13 r/4848 fix(tvix/eval): force value in builtins.typeOfsterni2-0/+23
This prevents Nix programs to observe the "internal" type of thunks. Possibly .type_of() is also an area of the runtime where we should panic if "internal" would ever be returned. Change-Id: I9f358044c48ad64896fb6a1b1a42f00a29efac00 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6539 Autosubmit: sterni <sternenseemann@systemli.org> Reviewed-by: wpcarro <wpcarro@gmail.com> Reviewed-by: grfn <grfn@gws.fyi> Reviewed-by: tazjin <tazjin@tvl.su> Tested-by: BuildkiteCI
2022-09-11 r/4809 fix(tvix/eval): place plain inherits in correct stack slotssterni2-0/+21
We need to make sure that we compile all plain inherits in a let expression before declaring any other locals. Plain inherits are special in the sense that they can never be recursive, instead resolving to a higher scope. Thus we need to compile their value, before declaring them. If we don't do that, before any other local can be declared, we cause a situation where the plain inherits' values are placed into other locals' stack slots. Note that we can't integrate the plain inherit compilation into the regular 2-3 phase model where we defer the compilation of the value or we'd compile `let inherit x; in …` as `let x = x; in …`. Change-Id: I951d5df3c9661a054e12401546875f4685b5bf08 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6496 Tested-by: BuildkiteCI Reviewed-by: tazjin <tazjin@tvl.su> Reviewed-by: sterni <sternenseemann@systemli.org>
2022-09-11 r/4808 test(tvix/eval): add test for mutually recursive let bindingssterni2-0/+15
This test shows that let bindings' dependencies can form a cyclical graph, so we need to use thunking to break this cycle. Change-Id: I2a4de71fd7024f3d3d1166154784139a82f39411 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6495 Tested-by: BuildkiteCI Reviewed-by: tazjin <tazjin@tvl.su> Reviewed-by: sterni <sternenseemann@systemli.org>
2022-09-11 r/4807 fix(tvix/eval): wrap asserts in a thunksterni2-0/+9
As the new test case demonstrates, asserts need to be evaluated lazily. Change-Id: I808046722c5a504e9497855ca5026d255c7a4c34 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6494 Tested-by: BuildkiteCI Reviewed-by: tazjin <tazjin@tvl.su> Reviewed-by: sterni <sternenseemann@systemli.org>
2022-09-11 r/4806 test(tvix/eval): test “useful” plain inheritssterni2-0/+10
Change-Id: Ic4700f0618a393e45a2ee7c70045edff97e30c49 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6493 Tested-by: BuildkiteCI Reviewed-by: tazjin <tazjin@tvl.su> Reviewed-by: sterni <sternenseemann@systemli.org>
2022-09-11 r/4805 fix(tvix/eval): declare let inherit (from) locals before compilingsterni4-2/+20
The recent change that split declaration of let based locals and the compilation of their values did not touch locals bound by inherit in let. These were previously declared and compiled immediately before starting to work on the other locals introduced in a let. In the case of plain inherits, this behavior is kept in this change, because there's nothing wrong with it: The value of a plain inherit will always resolve to a higher scope, either statically or dynamically. Since inherit (from) expression might refer to other locals bound in the same let, we need to handle them in the same three steps as ordinary let based locals: 1. We need to declare the (uninitialised) locals. 2. We need to compile the expression that obtains their value. For this, we create a new thunk, since the from expression may very well return a thunk which we need to force before selecting the value we are interested in. 3. Thunks need to be finalised. For 1., we create an extra pass over the inherits that already declares and initialises plain inherits and notes inherit (from) expressions in the entries vector after declaring them. 2. only needs a bit of adapting to create the thunks for selecting if appropriate, the rest of the existing code can be reused. Change-Id: Ie4ac1c0f9ffcbf7c07c452036aa8e577443af773 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6490 Tested-by: BuildkiteCI Reviewed-by: sterni <sternenseemann@systemli.org> Reviewed-by: tazjin <tazjin@tvl.su>
2022-09-11 r/4802 fix(tvix/eval): thunk all uses of `with`Vincent Ambo4-0/+19
With this all other "weird scope" logic starts working for `with` as well. Change-Id: I0ea1d8c5fbd9cec5084bd574224f77b71ff2b487 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6487 Tested-by: BuildkiteCI Reviewed-by: sterni <sternenseemann@systemli.org>
2022-09-11 r/4798 fix(tvix/eval): correctly account for slots during list constructionVincent Ambo2-0/+14
Similarly to attribute sets, list elements can be arbitrary expressions and their (temporary) stack slots during construction must be accounted for by the compiler. Change-Id: I3b6f7927860627fd867c64d0cab9104fd636d4f5 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6470 Tested-by: BuildkiteCI Reviewed-by: sterni <sternenseemann@systemli.org>
2022-09-11 r/4796 fix(tvix/eval): account for attrset temporaries during constructionVincent Ambo4-0/+21
The temporaries left on the stack as operands to `OpAttrs` must be accounted for in the locals array in order for operations within them to receive correct slots. Some test cases that were previously broken have been added. Change-Id: Ib52b629bbdf7931f63fd45a45af1073022da923c Reviewed-on: https://cl.tvl.fyi/c/depot/+/6468 Tested-by: BuildkiteCI Reviewed-by: sterni <sternenseemann@systemli.org>
2022-09-08 r/4770 feat(tvix/eval): thunk binary operations and select expressionsVincent Ambo2-0/+8
With this, most cases of `fix` in attribute sets will work correctly. A simple test exercising both has been added. Change-Id: I70fd431177bb6e48ecb33a87518b050c4c3d1c09 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6437 Reviewed-by: sterni <sternenseemann@systemli.org> Tested-by: BuildkiteCI
2022-09-08 r/4764 test(tvix/eval): add test for stack slot accounting edge-caseVincent Ambo2-0/+18
This was fixed by some of the previous commits around scopes. It's somewhat similar to a few other tests, but I had this one failing earlier and everything else succeeding, so it is useful to keep it around for sure. Change-Id: Ie6cf372b5c805daf992cd87aeb3dfe91542c381c Reviewed-on: https://cl.tvl.fyi/c/depot/+/6431 Reviewed-by: sterni <sternenseemann@systemli.org> Tested-by: BuildkiteCI
2022-09-08 r/4762 fix(tvix/eval): consider local depth when deciding to deferVincent Ambo2-0/+11
Deferred local upvalues can *only* occur at the same depth as the thing that is closing over them, but there are various situations with scope nesting where the actual stack indexes of the local and the closer look like a deferred value is being accessed. To fix this, simply compare the depth as well. Change-Id: Ice77424cc87ab0a2c4f01379e68d4399a917b12b Reviewed-on: https://cl.tvl.fyi/c/depot/+/6429 Reviewed-by: sterni <sternenseemann@systemli.org> Tested-by: BuildkiteCI
2022-09-08 r/4761 chore(tvix/eval): remove accidentally duplicated testVincent Ambo2-3/+0
This is the same as `eval-okay-attrs-simple-inherit`. Change-Id: I23878accc6cd62c16ec96601239838a385d31306 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6428 Reviewed-by: sterni <sternenseemann@systemli.org> Tested-by: BuildkiteCI
2022-09-08 r/4743 fix(tvix/eval): inherit scope poisoning data in nested contextsVincent Ambo2-0/+5
Scope poisoning must be inherited across lambda context boundaries, e.g. if an outer scope has a poisoned `null`, any lambdas defined on the same level must reference that poisoned identifier correctly. Change-Id: I1aac64e1c048a6f3bacadb6d78ed295fa439e8b4 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6410 Reviewed-by: sterni <sternenseemann@systemli.org> Tested-by: BuildkiteCI
2022-09-07 r/4740 feat(tvix/eval): Support builtins.lengthWilliam Carroll2-0/+6
Get the length of a list Change-Id: I41d91e96d833269541a1b3c23b7cc879f96d1e5a Reviewed-on: https://cl.tvl.fyi/c/depot/+/6407 Tested-by: BuildkiteCI Reviewed-by: sterni <sternenseemann@systemli.org>
2022-09-07 r/4739 feat(tvix/eval): Support builtins.{mul,div}William Carroll4-0/+18
Multiplication and division :) Change-Id: I79e76f3b55b7e9b8d1eb09b3d9741140b4d75742 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6406 Tested-by: BuildkiteCI Reviewed-by: sterni <sternenseemann@systemli.org>
2022-09-07 r/4738 feat(tvix/eval): Support builtins.{add,sub}William Carroll4-0/+16
First pass at supporting `builtins` for tvix. The following tests appear to be WAI: ```shell $ cd tvix/eval $ cargo build $ cargo test ``` Change-Id: I27cce23d503b17a886d1109e285e8b4be4264977 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6405 Tested-by: BuildkiteCI Reviewed-by: sterni <sternenseemann@systemli.org>
2022-09-07 r/4705 feat(tvix/eval): semi-strictly evaluate output values of the VMVincent Ambo2-3/+1
This essentially makes the VM behave like `nix-instantiate --eval --strict`, i.e. data structures are traversed strictly and thunks are forced. Thunks embedded in closures are not forced. This allows us to re-enable tests that were disabled because they needed to output nested thunk contents, but is overall a behaviour that must be configurable later on, as it is not cmopatible with e.g. an evaluation of nixpkgs. Change-Id: I5303a5c8e4322feab1384fdb7712fecb950afca5 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6372 Reviewed-by: sterni <sternenseemann@systemli.org> Tested-by: BuildkiteCI
2022-09-07 r/4699 feat(tvix/eval): construct attribute sets lazilyVincent Ambo2-1/+3
This thunks the construction of attribute sets. Because Tvix does not currently have a "strict output" mode, a test had to be disabled that now displays a thunk representation. The test will be re-enabled once that is available. Change-Id: I360332be64cd5c154f9caea21828f6f1b37a265c Reviewed-on: https://cl.tvl.fyi/c/depot/+/6363 Tested-by: BuildkiteCI Reviewed-by: sterni <sternenseemann@systemli.org>
2022-09-07 r/4690 test(tvix/eval): test very simple late-bound identifier accessVincent Ambo2-0/+5
This is the simplest kind of thunk that can be created (and so far the only one the compiler knows how to create), in which an identifier inside a `let` encounters a value that is bound *after* it is initialised. Change-Id: I6ea4408a3baef1e7d5137365d70804283f2dbf8e Reviewed-on: https://cl.tvl.fyi/c/depot/+/6354 Tested-by: BuildkiteCI Reviewed-by: sterni <sternenseemann@systemli.org>
2022-09-07 r/4689 feat(tvix/eval): always emit OpForce as the last instructionVincent Ambo2-0/+8
Change-Id: Id70c987f654dc5d9b47db74e395281309762b468 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6353 Tested-by: BuildkiteCI Reviewed-by: sterni <sternenseemann@systemli.org>
2022-09-06 r/4671 test(tvix/eval): add a test case for nested, deferred upvaluesVincent Ambo2-0/+7
This test case was previously broken by the bug introduced by confusing local and stack indexes. Change-Id: Ibef299dad266c6105deac1da5dde112fe9f640b1 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6341 Tested-by: BuildkiteCI Reviewed-by: sterni <sternenseemann@systemli.org>
2022-09-06 r/4669 feat(tvix/eval): emit OpFinalise when local scopes are completeVincent Ambo2-0/+5
With this change, the runtime can correctly capture deferred upvalues. Change-Id: I1e43b7b1ac2553b1812424adfc8bd08ef77bf1ea Reviewed-on: https://cl.tvl.fyi/c/depot/+/6339 Tested-by: BuildkiteCI Reviewed-by: sterni <sternenseemann@systemli.org>
2022-09-06 r/4659 fix(tvix/eval): instantiate *new* closures from blueprints each timeVincent Ambo2-0/+8
The previous closure refactoring introduced a bug in which the same closure object would get mutated constantly for each instance of a closure, which is incorrect behaviour. This commit instead introduces an explicit new Value variant for the internal "blueprint" that the compiler generates (essentially just the lambda) and uses this variant to construct the closure at runtime. If the blueprint ever leaks out to a user somehow that is a critical bug and tvix-eval will panic. As a ~treat~ test for this, the fibonacci function is being used as it is a self-recursive closure (i.e. different instantiations of the same "blueprint") getting called with different values and it's good to have it around. Change-Id: I485de675e9bb0c599ed7d5dc0f001eb34ab4c15f Reviewed-on: https://cl.tvl.fyi/c/depot/+/6323 Tested-by: BuildkiteCI Reviewed-by: sterni <sternenseemann@systemli.org>
2022-09-06 r/4658 fix(tvix/eval): correctly thread through dynamic upvaluesVincent Ambo2-0/+19
This puts together the puzzle pieces for threading dynamic upvalues (that is, upvalues resolved from the `with`-stack) all the way through. Reading the test case enclosed in this commit and walking through it is recommended to understand what problem is being tackled here. In short, because the compiler can not statically know *which* with-scope a dynamic argument is resolved from it needs to lay the groundwork for resolving from *all* possible scopes. There are multiple different approaches to doing this. The approach chosen in this commit is that if a dynamic upvalue is detected, the compiler will emit instructions to close over this dynamic value in *all* enclosing lambda contexts. It uses a new instruction for this that will leave around a sentinel value in case an identifier could not be resolved, and wire the location of this found value (or sentinel) up through the upvalues to the next level of nesting. In this tradeoff, tvix potentially closes over more upvalues than are needed (but in practice, how often do people create *really* deep `with`-stacks? and in *this* kind of code situation? maybe we should even warn for this!) but avoids keeping the entire attribute sets themselves around. Looking at the test case, each surrounding closure will close over *all* dynamic identifiers that are referenced later on visible to it, but only the last one for each identifier will actually end up being used. This also covers our bases for an additional edge-case this creates, in which an identifier potentially resolves to a dynamic upvalue *and* to a dynamic value within the function's own scope (again, would anyone really do this?) by introducing a resolution instruction for that particular case. There is likely some potential for cleaning up this code which is quite ugly in some parts, but as this implementation is now carefully calibrated to work I decided it is time to commit it and clean it up in subsequent commits. Change-Id: Ib701e3e6da39bd2c95938d1384036ff4f9fb3749 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6322 Tested-by: BuildkiteCI Reviewed-by: sterni <sternenseemann@systemli.org>
2022-09-06 r/4655 fix(tvix/eval): correctly resolve dynamic upvalues one scope upVincent Ambo4-0/+22
This does not yet correctly resolve them if they are more than one scope up, however. Change-Id: I6687073c60aee0282f2b6ffc98b34c1e96a60f20 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6319 Tested-by: BuildkiteCI Reviewed-by: sterni <sternenseemann@systemli.org>
2022-09-06 r/4653 feat(tvix/eval): implement capture of self-recursive upvaluesVincent Ambo2-0/+5
With this change, it becomes possible for functions to call themselves as they are being defined in local bindings. Change-Id: Ib46a39ba17b1452b5673d96fa729d633d237241a Reviewed-on: https://cl.tvl.fyi/c/depot/+/6314 Tested-by: BuildkiteCI Reviewed-by: sterni <sternenseemann@systemli.org>
2022-09-04 r/4635 feat(tvix/eval): implement upvalue resolution in `with` scopesVincent Ambo2-0/+6
These need to be handled specially by the runtime if the compiler determines that a given local must be resolved via `with`. Note that this implementation has a bug: It currently allows `with` inside of nested lambdas to shadow statically known identifiers. This will be cleaned up in the next commit. Change-Id: If196b99cbd1a0f2dbb4a40a0e88cdb09a009c6b9 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6299 Tested-by: BuildkiteCI Reviewed-by: sterni <sternenseemann@systemli.org>
2022-09-04 r/4632 test(tvix/eval): add tests for very simple closuresVincent Ambo4-0/+4
Change-Id: Ib8287ade4d5df6d29e1812fb2d349cee5d92ca6a Reviewed-on: https://cl.tvl.fyi/c/depot/+/6296 Tested-by: BuildkiteCI Reviewed-by: sterni <sternenseemann@systemli.org>
2022-09-03 r/4610 test(tvix/eval): add a test for float representationVincent Ambo2-0/+3
Change-Id: I4893a37719b9bf08b35963d48e6851a194a08aa7 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6274 Reviewed-by: grfn <grfn@gws.fyi> Tested-by: BuildkiteCI
2022-09-03 r/4607 fix(tvix/eval): correctly escape `${` in stringsVincent Ambo2-1/+2
Without this escape, it is possible for Nix to produce escaped representations which are not literal Nix values again. This was fixed in upstream Nix in https://github.com/NixOS/nix/pull/4012 (though only for eval, not in the REPL) and the updated test is picked from upstream after that commit. Because we run the C++ Nix tests against our test suite as well, this also bumps our custom Nix 2.3 to a commit that includes the cherry-picked fix from the PR above. Change-Id: I478547ade65f655c606ec46f7143932064192283 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6271 Reviewed-by: grfn <grfn@gws.fyi> Reviewed-by: sterni <sternenseemann@systemli.org> Tested-by: BuildkiteCI
2022-09-02 r/4598 fix(tvix/eval): consider `let ... inherit ...` in dynamic scopesVincent Ambo2-0/+16
In conditions where no dynamic identifiers exist in a scope, inheriting is usually a no-op - *unless* the identifier is not statically known and the scope has a non-empty `with`-stack. Change-Id: Iff4138d9cd4c56e844bc574203708dacc11c3f73 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6264 Reviewed-by: sterni <sternenseemann@systemli.org> Tested-by: BuildkiteCI
2022-09-02 r/4589 test(tvix/eval): add a simple test for builtins resolutionVincent Ambo2-0/+7
Change-Id: I91f54778b8a17f3448664c21308de656b4b04b3e Reviewed-on: https://cl.tvl.fyi/c/depot/+/6255 Tested-by: BuildkiteCI Reviewed-by: sterni <sternenseemann@systemli.org>
2022-09-02 r/4584 feat(tvix/eval): compile function applicationsVincent Ambo2-0/+3
Change-Id: I1b9230601895a1f09ef1a8037201147020b85f36 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6250 Reviewed-by: sterni <sternenseemann@systemli.org> Reviewed-by: grfn <grfn@gws.fyi> Tested-by: BuildkiteCI
2022-09-01 r/4563 refactor(tvix/eval): use pretty_assertions for testsVincent Ambo1-4/+5
This makes for much more readable output especially when long strings are involved. Change-Id: I43dd73a0480535d7181a760788c42883a9b083f8 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6229 Tested-by: BuildkiteCI Reviewed-by: sterni <sternenseemann@systemli.org>
2022-08-31 r/4561 feat(tvix/eval): implement scope poisoning for true/false/nullVincent Ambo4-0/+15
These tokens are optionally parsed as identifiers by Nix, which means that within any scopes that resolve them the compiler needs to track whether they have been overridden to know whether to emit the literal instructions or resolve a variable. This is implemented by a new concept of "scope poisoning", where the compiler's scope structure tracks whether or not any builtin identifiers have been overridden. Change-Id: I3ab711146e229f843f6e1f0343385382ee0aecb6 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6227 Tested-by: BuildkiteCI Reviewed-by: sterni <sternenseemann@systemli.org> Reviewed-by: grfn <grfn@gws.fyi>
2022-08-31 r/4560 refactor(tvix/eval): simplify `let ... in ...` before recursionVincent Ambo2-0/+8
While full recursion through thunking is not available, there are actually incorrect behaviours introduced by declaring before binding (example in the newly introduced test). This commit simplifies the implementation to avoid this issue, and also because I intend to explore a bit more how far we can get in non left-to-right bindings *without* introducing thunks immediately. Change-Id: I21fd3007ac3946570639772d7d624d70bd209958 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6226 Tested-by: BuildkiteCI Reviewed-by: sterni <sternenseemann@systemli.org> Reviewed-by: grfn <grfn@gws.fyi>
2022-08-31 r/4559 test(tvix/eval): add basic tests for with expressionsVincent Ambo4-0/+11
Change-Id: I94664090e7a2b060dfbe21c1eeb859fb31e417b0 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6225 Tested-by: BuildkiteCI Reviewed-by: sterni <sternenseemann@systemli.org> Reviewed-by: grfn <grfn@gws.fyi>
2022-08-31 r/4549 feat(tvix/eval): implement inherit in let expressionsVincent Ambo2-0/+9
Note that at this point recursive bindings do not yet work in either attrsets or let, so inheriting from the same scope is generally not possible yet. Change-Id: I6ca820d04b8ded5c22fb7ea18e2ec203bcaa8e9c Reviewed-on: https://cl.tvl.fyi/c/depot/+/6215 Reviewed-by: sterni <sternenseemann@systemli.org> Reviewed-by: grfn <grfn@gws.fyi> Tested-by: BuildkiteCI
2022-08-31 r/4548 feat(tvix/eval): implement `inherit` in attribute set literalsVincent Ambo4-0/+6
Straightforward implementation, evaluating the elements of an inherit and preparing the stack so that `OpAttrs` sees all relevant values when constructing the attribute set itself. The emitted instructions for inheriting a lot of values from the same attribute set are inefficient, but it's too early to say whether this actually matters. Change-Id: Icb55a20936d4ef77173f34433811c5fa5d2c9ecc Reviewed-on: https://cl.tvl.fyi/c/depot/+/6214 Reviewed-by: grfn <grfn@gws.fyi> Tested-by: BuildkiteCI
2022-08-30 r/4545 feat(tvix/eval): Implement inherit from outer scope in attrsVincent Ambo2-0/+5
Change-Id: I97fa45059b7f2cbe96eb60bd1821e3e25832df66 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6212 Reviewed-by: grfn <grfn@gws.fyi> Tested-by: BuildkiteCI
2022-08-30 r/4544 fix(tvix/eval): `?` operator should use OpAttrsOrNotFoundVincent Ambo2-0/+4
Using `OpAttrSelect`, the ? operator will fail when encountering a nested value that is not an attribute set. This however breaks valid code, such as: { bs = 42; } ? bs.a.b The fix is simply to use the same operator used in the `or` statement, which leaves a sentinal on the stack if a field is not found or the value is not an attribute set. Change-Id: Ib28fc8a96e6d592b4cdbc3e65ba129ad8faecd66 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6211 Reviewed-by: grfn <grfn@gws.fyi> Tested-by: BuildkiteCI
2022-08-30 r/4543 fix(tvix/eval): `or` should handle non-attrset values, tooVincent Ambo2-0/+3
If a nested attrpath encounters a non-set value, the sentinel value denoting a lack of next values should be emitted. This mirrors the behaviour of Nix. Change-Id: Ia80443d5a11243cc6d98dcab1249a3f5fdf77e27 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6210 Reviewed-by: grfn <grfn@gws.fyi> Tested-by: BuildkiteCI
2022-08-30 r/4542 fix(tvix/eval): allow use of ? operator on non-set typesVincent Ambo2-0/+4
Nix allows this, but always returns false. Tvix needs to do the same. Change-Id: Ic9eec90834a0d0969eea5316d5c25032d3691d94 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6209 Reviewed-by: grfn <grfn@gws.fyi> Tested-by: BuildkiteCI
2022-08-30 r/4541 fix(tvix/eval): emit correct count in OpAttrPathVincent Ambo2-0/+2
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-29 r/4527 test(tvix/eval): add basic tests for let expressionsVincent Ambo6-0/+17
Change-Id: I788504f0c1848a1422c99006bf659738df614716 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6191 Tested-by: BuildkiteCI Reviewed-by: grfn <grfn@gws.fyi>
2022-08-28 r/4519 feat(tvix/eval): resolve relative path literalsVincent Ambo1-2/+2
Resolves relative paths (e.g. `./foo`) either relative to the location of the Nix file, or relative to the working directory if none is supplied. Change-Id: I70ec574657b221b458015117a004b6e4a9c25a30 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6185 Tested-by: BuildkiteCI Reviewed-by: sterni <sternenseemann@systemli.org>