tvix/eval: miscompilation / crash around inherits and rec attrsets

#199
Opened by sterni at 2022-09-21T19·13+00

tvix-repl> rec { inherit (builtins) "tail"; }
=== compiled thunk @ 0x559c5ab4a190 (1 ops) ===
0x0      1  OpAttrs(Count(1))
=== compiled toplevel @ 0x559c5ab4bb70 (2 ops) ===
0x0      1  OpConstant(internal[thunk]@0)
0x1      |  OpForce
thread 'main' panicked at 'attempt to subtract with overflow', src/vm.rs:605:61
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
tvix-repl> rec { inherit; }
=== compiled thunk @ 0x555a17a5d3b0 (1 ops) ===
0x0      1  OpAttrs(Count(1))
=== compiled toplevel @ 0x555a17a64df0 (2 ops) ===
0x0      1  OpConstant(internal[thunk]@0)
0x1      |  OpForce
thread 'main' panicked at 'attempt to subtract with overflow', src/vm.rs:605:61
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

The reason for this miscompilation that compile_recursive_scope won't actually find any bindings to compile (in the case of the string inherit (which appears in the C++ test suite), it doesn't show up in the idents() iterator), but .entries().count() reports 1 in both cases, causing the miscompilation causing the crash:

            self.push_op(OpCode::OpAttrs(Count(node.entries().count())), &node);

Workaround seems to be to track the count manually once again, the question is of course what of this is an rnix bug and what is our fault.

  1. Hm, we could track the count manually but it does seem a bit like an rnix bug to me.

    tazjin at 2022-09-22T19·32+00

  2. Fixed in cl/6747 and cl/6749.

    There were actually two slightly different strange issues at play.

    Example of this working: https://tvixbolt.tvl.su/?code=let+a+%3D+42%3B%0Ain+rec+%7B%0A++inherit%3B%0A++inherit+%22a%22%3B%0A%7D&trace=false

    tazjin at 2022-09-22T23·34+00

  3. tazjin closed this issue at 2022-09-23T00·27+00