about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--tvix/eval/src/compiler/mod.rs2
-rw-r--r--tvix/eval/src/value/mod.rs8
-rw-r--r--tvix/eval/src/vm.rs24
3 files changed, 22 insertions, 12 deletions
diff --git a/tvix/eval/src/compiler/mod.rs b/tvix/eval/src/compiler/mod.rs
index e3076246de33..11537e76b5c9 100644
--- a/tvix/eval/src/compiler/mod.rs
+++ b/tvix/eval/src/compiler/mod.rs
@@ -296,7 +296,7 @@ impl Compiler<'_> {
             let path = &raw_path[1..(raw_path.len() - 1)];
             // Make a thunk to resolve the path (without using `findFile`, at least for now?)
             return self.thunk(slot, node, move |c, _| {
-                c.emit_constant(path.into(), node);
+                c.emit_constant(Value::UnresolvedPath(path.into()), node);
                 c.push_op(OpCode::OpFindFile, node);
             });
         } else {
diff --git a/tvix/eval/src/value/mod.rs b/tvix/eval/src/value/mod.rs
index 9231e91bbe8b..93e194e37940 100644
--- a/tvix/eval/src/value/mod.rs
+++ b/tvix/eval/src/value/mod.rs
@@ -46,6 +46,7 @@ pub enum Value {
     AttrNotFound,
     Blueprint(Rc<Lambda>),
     DeferredUpvalue(StackIdx),
+    UnresolvedPath(PathBuf),
 }
 
 // Helper macros to generate the to_*/as_* macros while accounting for
@@ -240,7 +241,8 @@ impl Value {
 
             (Value::AttrNotFound, _)
             | (Value::Blueprint(_), _)
-            | (Value::DeferredUpvalue(_), _) => {
+            | (Value::DeferredUpvalue(_), _)
+            | (Value::UnresolvedPath(_), _) => {
                 panic!("tvix bug: .coerce_to_string() called on internal value")
             }
         }
@@ -262,7 +264,8 @@ impl Value {
             Value::Thunk(_)
             | Value::AttrNotFound
             | Value::Blueprint(_)
-            | Value::DeferredUpvalue(_) => "internal",
+            | Value::DeferredUpvalue(_)
+            | Value::UnresolvedPath(_) => "internal",
         }
     }
 
@@ -362,6 +365,7 @@ impl Display for Value {
             Value::AttrNotFound => f.write_str("internal[not found]"),
             Value::Blueprint(_) => f.write_str("internal[blueprint]"),
             Value::DeferredUpvalue(_) => f.write_str("internal[deferred_upvalue]"),
+            Value::UnresolvedPath(_) => f.write_str("internal[unresolved_path]"),
         }
     }
 }
diff --git a/tvix/eval/src/vm.rs b/tvix/eval/src/vm.rs
index 252635de56d0..05adec5f6ea6 100644
--- a/tvix/eval/src/vm.rs
+++ b/tvix/eval/src/vm.rs
@@ -524,14 +524,17 @@ impl<'o> VM<'o> {
                 self.push(Value::String(string));
             }
 
-            OpCode::OpFindFile => {
-                let path = self.pop().to_str().map_err(|e| self.error(e))?;
-                let resolved = self
-                    .nix_search_path
-                    .resolve(path)
-                    .map_err(|e| self.error(e))?;
-                self.push(resolved.into());
-            }
+            OpCode::OpFindFile => match self.pop() {
+                Value::UnresolvedPath(path) => {
+                    let resolved = self
+                        .nix_search_path
+                        .resolve(path)
+                        .map_err(|e| self.error(e))?;
+                    self.push(resolved.into());
+                }
+
+                _ => panic!("tvix compiler bug: OpFindFile called on non-UnresolvedPath"),
+            },
 
             OpCode::OpJump(JumpOffset(offset)) => {
                 debug_assert!(offset != 0);
@@ -836,7 +839,10 @@ impl<'o> VM<'o> {
 
             // If any of these internal values are encountered here a
             // critical error has happened (likely a compiler bug).
-            Value::AttrNotFound | Value::Blueprint(_) | Value::DeferredUpvalue(_) => {
+            Value::AttrNotFound
+            | Value::Blueprint(_)
+            | Value::DeferredUpvalue(_)
+            | Value::UnresolvedPath(_) => {
                 panic!("tvix bug: internal value left on stack: {:?}", value)
             }