From 23a5caabec5617c01d5629bd50dd7e7649cbe5a6 Mon Sep 17 00:00:00 2001 From: Vincent Ambo Date: Tue, 30 Aug 2022 19:55:04 +0300 Subject: feat(tvix/eval): construct attribute sets lazily 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 --- tvix/eval/src/compiler/mod.rs | 12 ++++++++++-- .../src/tests/tvix_tests/disabled-identity-nested-attrs.nix | 3 +++ tvix/eval/src/tests/tvix_tests/identity-nested-attrs.nix | 1 - 3 files changed, 13 insertions(+), 3 deletions(-) create mode 100644 tvix/eval/src/tests/tvix_tests/disabled-identity-nested-attrs.nix delete mode 100644 tvix/eval/src/tests/tvix_tests/identity-nested-attrs.nix (limited to 'tvix/eval') diff --git a/tvix/eval/src/compiler/mod.rs b/tvix/eval/src/compiler/mod.rs index 96c864110137..b1dec5df1db2 100644 --- a/tvix/eval/src/compiler/mod.rs +++ b/tvix/eval/src/compiler/mod.rs @@ -115,7 +115,7 @@ impl Compiler { ast::Expr::BinOp(op) => self.compile_binop(slot, op), ast::Expr::HasAttr(has_attr) => self.compile_has_attr(slot, has_attr), ast::Expr::List(list) => self.compile_list(slot, list), - ast::Expr::AttrSet(attrs) => self.compile_attr_set(slot, attrs), + ast::Expr::AttrSet(attrs) => self.thunk(slot, move |c, s| c.compile_attr_set(s, attrs)), ast::Expr::Select(select) => self.compile_select(slot, select), ast::Expr::Assert(assert) => self.compile_assert(slot, assert), ast::Expr::IfElse(if_else) => self.compile_if_else(slot, if_else), @@ -422,7 +422,8 @@ impl Compiler { for ident in inherit.idents() { count += 1; - // First emit the identifier itself + // First emit the identifier itself (this + // becomes the new key). self.emit_literal_ident(&ident); // Then emit the node that we're inheriting @@ -434,6 +435,7 @@ impl Compiler { // than pushing/popping the same attrs // potentially a lot of times. self.compile(slot, from.expr().unwrap()); + self.emit_force(); self.emit_literal_ident(&ident); self.chunk().push_op(OpCode::OpAttrsSelect); } @@ -494,6 +496,7 @@ impl Compiler { // Push the set onto the stack self.compile(slot, set); + self.emit_force(); // Compile each key fragment and emit access instructions. // @@ -542,6 +545,7 @@ impl Compiler { default: ast::Expr, ) { self.compile(slot, set); + self.emit_force(); let mut jumps = vec![]; for fragment in path.attrs() { @@ -645,6 +649,8 @@ impl Compiler { Some(from) => { for ident in inherit.idents() { self.compile(slot, from.expr().unwrap()); + self.emit_force(); + self.emit_literal_ident(&ident); self.chunk().push_op(OpCode::OpAttrsSelect); let idx = self.declare_local( @@ -788,6 +794,8 @@ impl Compiler { // resolve that directly (thus avoiding duplication on the // stack). self.compile(slot, node.namespace().unwrap()); + self.emit_force(); + let local_idx = self.scope_mut().declare_phantom(); let with_idx = self.scope().stack_index(local_idx); diff --git a/tvix/eval/src/tests/tvix_tests/disabled-identity-nested-attrs.nix b/tvix/eval/src/tests/tvix_tests/disabled-identity-nested-attrs.nix new file mode 100644 index 000000000000..f8dacf3e084a --- /dev/null +++ b/tvix/eval/src/tests/tvix_tests/disabled-identity-nested-attrs.nix @@ -0,0 +1,3 @@ +# TODO: temporarily disabled because need "strict output" (b is +# thunked) +{ a = { b = null; }; } diff --git a/tvix/eval/src/tests/tvix_tests/identity-nested-attrs.nix b/tvix/eval/src/tests/tvix_tests/identity-nested-attrs.nix deleted file mode 100644 index 6a139452ef28..000000000000 --- a/tvix/eval/src/tests/tvix_tests/identity-nested-attrs.nix +++ /dev/null @@ -1 +0,0 @@ -{ a = { b = null; }; } -- cgit 1.4.1