about summary refs log tree commit diff
path: root/tvix/eval/src
diff options
context:
space:
mode:
Diffstat (limited to 'tvix/eval/src')
-rw-r--r--tvix/eval/src/compiler/bindings.rs11
-rw-r--r--tvix/eval/src/tests/tvix_tests/eval-okay-lazy-with-nested.exp1
-rw-r--r--tvix/eval/src/tests/tvix_tests/eval-okay-lazy-with-nested.nix5
-rw-r--r--tvix/eval/src/tests/tvix_tests/eval-okay-lazy-with.nix2
4 files changed, 16 insertions, 3 deletions
diff --git a/tvix/eval/src/compiler/bindings.rs b/tvix/eval/src/compiler/bindings.rs
index 9f7df1fdca19..4283b21276d4 100644
--- a/tvix/eval/src/compiler/bindings.rs
+++ b/tvix/eval/src/compiler/bindings.rs
@@ -694,9 +694,16 @@ impl Compiler<'_> {
 
                 // If there is a non-empty `with`-stack (or a parent context
                 // with one), emit a runtime dynamic resolution instruction.
+                //
+                // Since it is possible for users to e.g. assign a variable to a
+                // dynamic resolution without actually using it, this operation
+                // is wrapped in an extra thunk.
                 if self.has_dynamic_ancestor() {
-                    self.emit_constant(Value::String(SmolStr::new(ident).into()), node);
-                    self.push_op(OpCode::OpResolveWith, node);
+                    self.thunk(slot, node, |c, _| {
+                        c.context_mut().captures_with_stack = true;
+                        c.emit_constant(Value::String(SmolStr::new(ident).into()), node);
+                        c.push_op(OpCode::OpResolveWith, node);
+                    });
                     return;
                 }
 
diff --git a/tvix/eval/src/tests/tvix_tests/eval-okay-lazy-with-nested.exp b/tvix/eval/src/tests/tvix_tests/eval-okay-lazy-with-nested.exp
new file mode 100644
index 000000000000..d81cc0710eb6
--- /dev/null
+++ b/tvix/eval/src/tests/tvix_tests/eval-okay-lazy-with-nested.exp
@@ -0,0 +1 @@
+42
diff --git a/tvix/eval/src/tests/tvix_tests/eval-okay-lazy-with-nested.nix b/tvix/eval/src/tests/tvix_tests/eval-okay-lazy-with-nested.nix
new file mode 100644
index 000000000000..22ac14b3f19e
--- /dev/null
+++ b/tvix/eval/src/tests/tvix_tests/eval-okay-lazy-with-nested.nix
@@ -0,0 +1,5 @@
+# The 'namespace' of a with should only be evaluated if an identifier
+# from it is actually accessed.
+
+with (abort "should not be evaluated");
+let a = dynamic; in 42
diff --git a/tvix/eval/src/tests/tvix_tests/eval-okay-lazy-with.nix b/tvix/eval/src/tests/tvix_tests/eval-okay-lazy-with.nix
index e4377df97eeb..8b1a0191dcc0 100644
--- a/tvix/eval/src/tests/tvix_tests/eval-okay-lazy-with.nix
+++ b/tvix/eval/src/tests/tvix_tests/eval-okay-lazy-with.nix
@@ -1,6 +1,6 @@
 # The 'namespace' of a with should only be evaluated if an identifier
 # from it is actually accessed.
 
-with (builtins.throw "should not occur");
+with (abort "should not be evaluated");
 
 42