tvl-depot/tvix/eval
sterni 4516cd09c5 fix(tvix/eval): only finalise formal arguments if defaulting
When dealing with a formal argument in a function argument pattern that
has a default expression, there are two different things that can happen
at runtime: Either we select its value from the passed attribute
successfully or we need to use the default expression. Both of these may
be thunks and both of these may need finalisers. However, in the former
case this is taken care of elsewhere, the value will always be finalised
already if necessary. In the latter case we may need to finalise the
thunk resulting from the default expression. However, the thunk
corresponding to the expression may never end up in the local's stack
slot. Since finalisation goes by stack slot (and not constants), we need
to prevent a case where we don't fall back to the default expression,
but finalise anyways.

Previously, we worked around this by making `OpFinalise` ignore
non-thunks. Since finalisation of already evaluated thunks still
crashed, the faulty compilation of function pattern arguments could
still cause a crash.

As a new approach, we reinstate the old behavior of `OpFinalise` to
crash whenever encountering something that is either not a thunk or
doesn't need finalisation. This can also help catching (similar)
miscompilations in the future. To then prevent the crash, we need to
track whether we have fallen back or not at runtime. This is done using
an additional phantom on the stack that holds a new `FinaliseRequest`
value. When it comes to finalisation we check this value and
conditionally execute `OpFinalise` based on its value.

Resolves b/261 and b/265 (partially).

Change-Id: Ic04fb80ec671a2ba11fa645090769c335fb7f58b
Reviewed-on: https://cl.tvl.fyi/c/depot/+/8705
Reviewed-by: tazjin <tazjin@tvl.su>
Tested-by: BuildkiteCI
Autosubmit: sterni <sternenseemann@systemli.org>
2023-06-20 10:07:44 +00:00
..
benches fix(tvix/eval): fix current clippy warnings 2022-12-25 18:25:06 +00:00
builtin-macros refactor(tvix/eval): flatten call stack of VM using generators 2023-03-13 20:30:59 +00:00
docs fix(tvix/eval): only finalise formal arguments if defaulting 2023-06-20 10:07:44 +00:00
proptest-regressions/value refactor(tvix/eval): flatten call stack of VM using generators 2023-03-13 20:30:59 +00:00
src fix(tvix/eval): only finalise formal arguments if defaulting 2023-06-20 10:07:44 +00:00
tests fix(tvix/eval): don't thunk home relative paths 2023-06-14 10:57:28 +00:00
.skip-subtree feat(tvix/tests): check in Nix' language test suite 2022-08-24 21:25:41 +00:00
build.rs feat(tvix/eval): implement builtins.currentSystem 2022-10-24 12:20:01 +00:00
Cargo.toml chore(tvix/*): bump to smol_str 0.2.0 2023-05-11 18:19:20 +00:00
default.nix refactor(tvix): build Rust projects using crate2nix 2022-12-15 17:26:45 +00:00
README.md docs(tvix/eval): update test suite documentation 2023-06-15 19:28:16 +00:00

Tvix Evaluator

This project implements an interpreter for the Nix programming language. You can experiment with an online version of the evaluator: tvixbolt.

The interpreter aims to be compatible with nixpkgs, on the foundation of Nix 2.3.

Important note: The evaluator is not yet feature-complete, and while the core mechanisms (compiler, runtime, ...) have stabilised somewhat, a lot of components are still changing rapidly.

Please contact TVL with any questions you might have.

Building tvix-eval

Please check the README.md one level up for instructions on how to build this.

The evaluator itself can also be built with standard Rust tooling (i.e. cargo build).

If you would like to clone only the evaluator and build it directly with Rust tooling, you can do:

git clone https://code.tvl.fyi/depot.git:/tvix/eval.git tvix-eval

cd tvix-eval && cargo build

Tests

Tvix currently has three language test suites for tvix-eval:

  • nix_tests and tvix_tests are based on the same mechanism borrowed from the C++ Nix implementation. They consist of Nix files as well as expected output (if applicable). The test cases are split into four categories: eval-okay (evaluates successfully with the expected output), eval-fail (fails to evaluate, no expected output), parse-okay (expression parses successfully, no expected output) and parse-fail (expression fails to parse, no expected output). Tvix currently ignores the last two types of test cases, since it doesn't implement its own parser.

    Both test suites have a notyetpassing directory. All test cases in here test behavior that is not yet supported by Tvix. They are considered to be expected failures, so you can't forget to move them into the test suite proper when fixing the incompatibility.

    Additionally, separate targets in the depot pipeline, under //tvix/verify-lang-tests, check both test suites (including notyetpassing directories) against C++ Nix 2.3 and the default C++ Nix version in nixpkgs. This way we can prevent accidentally introducing test cases for behavior that C++ Nix doesn't exhibit.

    • nix_tests has the test cases from C++ Nix's language test suite and is sporadically updated by manually syncing the directories. The notyetpassing directory shows how far it is until we pass it completely.

    • tvix_tests contains test cases written by the Tvix contributors. Some more or less duplicate test cases contained in nix_tests, but many cover relevant behavior that isn't by nix_tests. Consequently, it'd be nice to eventually merge the two test suites into a jointly maintained, common Nix language test suite.

      It also has a notyetpassing directory for missing behavior that is discovered while working on Tvix and isn't covered by the nix_tests suite.

  • nix_oracle can evaluate Nix expressions in Tvix and compare the result against C++ Nix (2.3) directly. Eventually it should gain the ability to property test generated Nix expressions. An additional feature is that it can evaluate expressions without --strict, so thunking behavior can be verified more easily.

rnix-parser

Tvix is written in memory of jD91mZM2, the author of rnix-parser who sadly passed away.

Tvix makes heavy use of rnix-parser in its bytecode compiler. The parser is now maintained by Nix community members.