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 <sternenseemann@systemli.org>
This commit is contained in:
parent
33059de431
commit
fd14eefed6
3 changed files with 32 additions and 1 deletions
|
@ -443,12 +443,29 @@ impl Compiler<'_, '_> {
|
||||||
fn compile_list(&mut self, slot: LocalIdx, node: ast::List) {
|
fn compile_list(&mut self, slot: LocalIdx, node: ast::List) {
|
||||||
let mut count = 0;
|
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() {
|
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;
|
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.push_op(OpCode::OpList(Count(count)), &node);
|
||||||
|
self.scope_mut().end_scope();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Compiles inherited values in an attribute set. Inherited
|
/// Compiles inherited values in an attribute set. Inherited
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
[ 1 2 3 ]
|
13
tvix/eval/src/tests/tvix_tests/eval-okay-with-in-list.nix
Normal file
13
tvix/eval/src/tests/tvix_tests/eval-okay-with-in-list.nix
Normal file
|
@ -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
|
||||||
|
]
|
Loading…
Reference in a new issue