about summary refs log tree commit diff
path: root/tvix/eval/src/compiler/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'tvix/eval/src/compiler/mod.rs')
-rw-r--r--tvix/eval/src/compiler/mod.rs24
1 files changed, 20 insertions, 4 deletions
diff --git a/tvix/eval/src/compiler/mod.rs b/tvix/eval/src/compiler/mod.rs
index 11d6d8231f09..78fe76ca01a9 100644
--- a/tvix/eval/src/compiler/mod.rs
+++ b/tvix/eval/src/compiler/mod.rs
@@ -702,6 +702,15 @@ impl Compiler {
                 if let Some(idx) =
                     self.resolve_dynamic_upvalue(self.contexts.len() - 1, ident.text())
                 {
+                    // Edge case: Current scope *also* has a non-empty
+                    // `with`-stack. This means we need to resolve
+                    // both in this scope, and in the upvalues.
+                    if self.scope().has_with() {
+                        self.emit_constant(Value::String(ident.text().into()));
+                        self.chunk().push_op(OpCode::OpResolveWithOrUpvalue(idx));
+                        return;
+                    }
+
                     self.chunk().push_op(OpCode::OpGetUpvalue(idx));
                     return;
                 }
@@ -810,11 +819,18 @@ impl Compiler {
         self.chunk().push_op(OpCode::OpClosure(closure_idx));
         for upvalue in compiled.scope.upvalues {
             match upvalue {
-                Upvalue::Stack(idx) => self.chunk().push_op(OpCode::DataLocalIdx(idx)),
-                Upvalue::Upvalue(idx) => self.chunk().push_op(OpCode::DataUpvalueIdx(idx)),
-                Upvalue::Dynamic { name, .. } => {
+                Upvalue::Stack(idx) => {
+                    self.chunk().push_op(OpCode::DataLocalIdx(idx));
+                }
+                Upvalue::Upvalue(idx) => {
+                    self.chunk().push_op(OpCode::DataUpvalueIdx(idx));
+                }
+                Upvalue::Dynamic { name, up } => {
                     let idx = self.chunk().push_constant(Value::String(name.into()));
-                    self.chunk().push_op(OpCode::DataDynamicIdx(idx))
+                    self.chunk().push_op(OpCode::DataDynamicIdx(idx));
+                    if let Some(up) = up {
+                        self.chunk().push_op(OpCode::DataDynamicAncestor(up));
+                    }
                 }
             };
         }