From fd14eefed6cdf0d0f5b14b516515660ced69181b Mon Sep 17 00:00:00 2001 From: Vincent Ambo Date: Tue, 6 Sep 2022 20:43:49 +0300 Subject: fix(tvix/eval): correctly account for slots during list construction Similarly to attribute sets, list elements can be arbitrary expressions and their (temporary) stack slots during construction must be accounted for by the compiler. Change-Id: I3b6f7927860627fd867c64d0cab9104fd636d4f5 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6470 Tested-by: BuildkiteCI Reviewed-by: sterni --- tvix/eval/src/compiler/mod.rs | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) (limited to 'tvix/eval/src/compiler/mod.rs') 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 -- cgit 1.4.1