diff options
author | Vincent Ambo <mail@tazj.in> | 2022-09-05T14·01+0300 |
---|---|---|
committer | tazjin <tazjin@tvl.su> | 2022-09-11T12·04+0000 |
commit | 27e69503a7374d7758a7c6145427265712d45f9c (patch) | |
tree | 50a41c04030cb3e922cf83d40dc335f758e4bbbf | |
parent | bb34665abdf82227abdf0fc726abe2df57f3193e (diff) |
fix(tvix/eval): avoid forcing with-target until absolutely necessary r/4793
Change-Id: I00efbbb8b9d3d22f32becf0919c6adf1be8b4b69 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6465 Tested-by: BuildkiteCI Reviewed-by: sterni <sternenseemann@systemli.org>
-rw-r--r-- | tvix/eval/src/compiler/mod.rs | 1 | ||||
-rw-r--r-- | tvix/eval/src/vm.rs | 15 |
2 files changed, 11 insertions, 5 deletions
diff --git a/tvix/eval/src/compiler/mod.rs b/tvix/eval/src/compiler/mod.rs index 6be2a1fb05a5..d05989562f66 100644 --- a/tvix/eval/src/compiler/mod.rs +++ b/tvix/eval/src/compiler/mod.rs @@ -862,7 +862,6 @@ impl Compiler<'_, '_> { // resolve that directly (thus avoiding duplication on the // stack). self.compile(slot, node.namespace().unwrap()); - self.emit_force(&node.namespace().unwrap()); let span = self.span_for(&node.namespace().unwrap()); diff --git a/tvix/eval/src/vm.rs b/tvix/eval/src/vm.rs index 89702a090fff..c124a653a019 100644 --- a/tvix/eval/src/vm.rs +++ b/tvix/eval/src/vm.rs @@ -635,10 +635,17 @@ impl<'o> VM<'o> { } /// Resolve a dynamic identifier through the with-stack at runtime. - fn resolve_with(&self, ident: &str) -> EvalResult<Value> { - for idx in self.with_stack.iter().rev() { - let with = fallible!(self, self.stack[*idx].to_attrs()); - match with.select(ident) { + fn resolve_with(&mut self, ident: &str) -> EvalResult<Value> { + // Iterate over the with_stack manually to avoid borrowing + // self, which is required for forcing the set. + for with_stack_idx in (0..self.with_stack.len()).rev() { + let with = self.stack[self.with_stack[with_stack_idx]].clone(); + + if let Value::Thunk(thunk) = &with { + fallible!(self, thunk.force(self)); + } + + match fallible!(self, with.to_attrs()).select(ident) { None => continue, Some(val) => return Ok(val.clone()), } |