about summary refs log tree commit diff
path: root/tvix/eval
diff options
context:
space:
mode:
Diffstat (limited to 'tvix/eval')
-rw-r--r--tvix/eval/src/compiler/mod.rs19
-rw-r--r--tvix/eval/src/tests/tvix_tests/eval-okay-with-in-list.exp1
-rw-r--r--tvix/eval/src/tests/tvix_tests/eval-okay-with-in-list.nix13
3 files changed, 32 insertions, 1 deletions
diff --git a/tvix/eval/src/compiler/mod.rs b/tvix/eval/src/compiler/mod.rs
index af64953f88ab..883129dbfa4d 100644
--- a/tvix/eval/src/compiler/mod.rs
+++ b/tvix/eval/src/compiler/mod.rs
@@ -443,12 +443,29 @@ impl Compiler<'_, '_> {
     fn compile_list(&mut self, slot: LocalIdx, node: ast::List) {
         let mut count = 0;
 
+        // Open a temporary scope to correctly account for stack items
+        // that exist during the construction.
+        self.begin_scope();
+
         for item in node.items() {
+            // Start tracing new stack slots from the second list
+            // element onwards. The first list element is located in
+            // the stack slot of the list itself.
+            let item_slot = match count {
+                0 => slot,
+                _ => {
+                    let item_span = self.span_for(&item);
+                    self.scope_mut().declare_phantom(item_span, false)
+                }
+            };
+
             count += 1;
-            self.compile(slot, item);
+            self.compile(item_slot, item);
+            self.scope_mut().mark_initialised(item_slot);
         }
 
         self.push_op(OpCode::OpList(Count(count)), &node);
+        self.scope_mut().end_scope();
     }
 
     /// Compiles inherited values in an attribute set. Inherited
diff --git a/tvix/eval/src/tests/tvix_tests/eval-okay-with-in-list.exp b/tvix/eval/src/tests/tvix_tests/eval-okay-with-in-list.exp
new file mode 100644
index 000000000000..5776134d0e41
--- /dev/null
+++ b/tvix/eval/src/tests/tvix_tests/eval-okay-with-in-list.exp
@@ -0,0 +1 @@
+[ 1 2 3 ]
diff --git a/tvix/eval/src/tests/tvix_tests/eval-okay-with-in-list.nix b/tvix/eval/src/tests/tvix_tests/eval-okay-with-in-list.nix
new file mode 100644
index 000000000000..bb62fdf31cd7
--- /dev/null
+++ b/tvix/eval/src/tests/tvix_tests/eval-okay-with-in-list.nix
@@ -0,0 +1,13 @@
+# This code causes a situation where a list element causes an
+# additional phantom value to temporarily be placed on the locals
+# stack, which must be correctly accounted for by the compiler.
+
+let
+  set = {
+    value = 2;
+  };
+in [
+  1
+  (with set; value)
+  3
+]