fix(tvix/eval): make tvix display values like nix-instantiate(1)

In order for the test suite we have currently to be comparable to C++
Nix, we need to display values in the same way. This was largely the
case except in some weird cases.

* <CODE> for thunks and <CYCLE> for repeated thunks (?) are already in
  use. <CODE> formatting is tested by the oracle test suite already.

* Instead of lambda, we need to use <LAMBDA>

* <<primop>> and <<primop-app>> (a formatting C++ Nix uses nowhere)
  now are <PRIMOP> and <PRIMOP-APP>.

We'll probably want to have a fancier display of values (in a separate
trait) down the line. This could be used for interactive usage, e.g. the
REPL or a potential debugger.

There is a peculiarity with C++ Nix 2.3 formatting primops: import is
considered a <<PRIMOP-APP>>, since it is internally implemented by means
of scopedImport. This implementation detail no longer leaks in C++ Nix
2.13 nor in Tvix.

<CYCLE> display is untested at the moment, since we exhibit a
discrepancy to C++ Nix 2.3. Our current detection is more similar to C++
Nix 2.13—luckily it is also the more consistent of the two. See also
b/245.

Change-Id: I1d534434b02e470bf5475b3758920ea81e3420dc
Reviewed-on: https://cl.tvl.fyi/c/depot/+/8760
Reviewed-by: tazjin <tazjin@tvl.su>
Autosubmit: sterni <sternenseemann@systemli.org>
Tested-by: BuildkiteCI
This commit is contained in:
sterni 2023-06-13 15:15:11 +02:00 committed by clbot
parent 9c7d1361c5
commit 0005737f11
9 changed files with 63 additions and 3 deletions

View file

@ -0,0 +1 @@
<PRIMOP>

View file

@ -0,0 +1,2 @@
# In C++ Nix 2.3 this used to be <PRIMOP-APP>
import

View file

@ -0,0 +1 @@
[ null true false 42 42 "foo\t\nbar" /home/arthur [ 1 2 3 ] <LAMBDA> <PRIMOP> <PRIMOP-APP> { hello = "world"; } ]

View file

@ -0,0 +1,16 @@
# Sanity check of how values are rendered by tvix vs. nix-instantiate(1).
# Ensures that we can use this test suite to compare against C++ Nix.
[
null
true
false
42
42.0
"foo\t\nbar"
/home/arthur
[ 1 2 3 ]
(x: x)
builtins.add
(builtins.substring 0 1)
{ hello = "world"; }
]

View file

@ -0,0 +1 @@
[ { car = 42; cdr = «repeated»; } [ «repeated» «repeated» «repeated» ] { val = 42; wal = «repeated»; xal = «repeated»; } { tail1 = «repeated»; tail2 = «repeated»; val = 42; } { tail1 = «repeated»; tail2 = «repeated»; val = 21; } ]

View file

@ -0,0 +1,34 @@
let
linkedList = {
car = 42;
cdr = linkedList;
};
list = [
linkedList
linkedList
linkedList
];
set = {
val = 42;
wal = set;
xal = set;
};
multiTail = {
val = 42;
tail1 = multiTail;
tail2 = multiTail;
};
in
[
linkedList
list
set
# In C++ Nix 2.3 these would be displayed differently
multiTail
(let multiTail = { val = 21; tail1 = multiTail; tail2 = multiTail; }; in multiTail)
]

View file

@ -121,9 +121,9 @@ impl Debug for Builtin {
impl Display for Builtin {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
if !self.0.partials.is_empty() {
f.write_str("<<primop-app>>")
f.write_str("<PRIMOP-APP>")
} else {
f.write_str("<<primop>>")
f.write_str("<PRIMOP>")
}
}
}

View file

@ -758,7 +758,8 @@ impl TotalDisplay for Value {
Value::Path(p) => p.display().fmt(f),
Value::Attrs(attrs) => attrs.total_fmt(f, set),
Value::List(list) => list.total_fmt(f, set),
Value::Closure(_) => f.write_str("lambda"), // TODO: print position
// TODO: fancy REPL display with position
Value::Closure(_) => f.write_str("<LAMBDA>"),
Value::Builtin(builtin) => builtin.fmt(f),
// Nix prints floats with a maximum precision of 5 digits

View file

@ -59,6 +59,10 @@ let
"eval-okay-getattrpos-functionargs.nix" = [ nix ];
# groupBy appeared (long) after 2.3
"eval-okay-builtins-groupby-thunk.nix" = [ nix ];
# import is no longer considered a curried primop in Nix > 2.3
"eval-okay-import-display.nix" = [ nix ];
# Cycle detection and formatting changed sometime after Nix 2.3
"eval-okay-cycle-display-cpp-nix-2.13.nix" = [ nix ];
};
runCppNixLangTests = cpp-nix: