diff --git a/tvix/eval/src/compiler/attrs.rs b/tvix/eval/src/compiler/attrs.rs index bb48ffbb0..c9897daac 100644 --- a/tvix/eval/src/compiler/attrs.rs +++ b/tvix/eval/src/compiler/attrs.rs @@ -113,12 +113,14 @@ impl Compiler<'_, '_> { pub(super) fn compile_has_attr(&mut self, slot: LocalIdx, node: ast::HasAttr) { // Put the attribute set on the stack. self.compile(slot, node.expr().unwrap()); + self.emit_force(&node); // Push all path fragments with an operation for fetching the // next nested element, for all fragments except the last one. for (count, fragment) in node.attrpath().unwrap().attrs().enumerate() { if count > 0 { self.push_op(OpCode::OpAttrsTrySelect, &fragment); + self.emit_force(&fragment); } self.compile_attr(slot, fragment); diff --git a/tvix/eval/src/tests/tvix_tests/eval-okay-nested-has-attrs.exp b/tvix/eval/src/tests/tvix_tests/eval-okay-nested-has-attrs.exp new file mode 100644 index 000000000..d2c1c04da --- /dev/null +++ b/tvix/eval/src/tests/tvix_tests/eval-okay-nested-has-attrs.exp @@ -0,0 +1 @@ +[ true true true true true true true false false false false false ] diff --git a/tvix/eval/src/tests/tvix_tests/eval-okay-nested-has-attrs.nix b/tvix/eval/src/tests/tvix_tests/eval-okay-nested-has-attrs.nix new file mode 100644 index 000000000..47dcec7a9 --- /dev/null +++ b/tvix/eval/src/tests/tvix_tests/eval-okay-nested-has-attrs.nix @@ -0,0 +1,26 @@ +let + set = { + a.b.c = 123; + foo = { + bar = 23; + }; + baz = 1; + }; + + tes = "random value"; +in + +[ + (set ? a) + (set ? a.b) + (set ? a.b.c) + (set ? foo) + (set ? foo.bar) + (set.foo ? bar) + (set ? baz) + (set ? x) + (set ? x.y.z) + (tes ? bar) + (tes ? x.y.z) + (null ? null) +]