diff options
Diffstat (limited to 'tvix/eval')
-rw-r--r-- | tvix/eval/src/compiler/mod.rs | 19 | ||||
-rw-r--r-- | tvix/eval/src/tests/tvix_tests/eval-okay-with-in-list.exp | 1 | ||||
-rw-r--r-- | tvix/eval/src/tests/tvix_tests/eval-okay-with-in-list.nix | 13 |
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 +] |