about summary refs log tree commit diff
path: root/tvix/eval
diff options
context:
space:
mode:
Diffstat (limited to 'tvix/eval')
-rw-r--r--tvix/eval/src/value/thunk.rs4
-rw-r--r--tvix/eval/src/vm.rs6
2 files changed, 9 insertions, 1 deletions
diff --git a/tvix/eval/src/value/thunk.rs b/tvix/eval/src/value/thunk.rs
index 549534b04ec7..5eee07a9e7ac 100644
--- a/tvix/eval/src/value/thunk.rs
+++ b/tvix/eval/src/value/thunk.rs
@@ -133,6 +133,10 @@ impl Thunk {
         }
     }
 
+    pub fn is_evaluated(&self) -> bool {
+        matches!(*self.0.borrow(), ThunkRepr::Evaluated(_))
+    }
+
     /// Returns a reference to the inner evaluated value of a thunk.
     /// It is an error to call this on a thunk that has not been
     /// forced, or is not otherwise known to be fully evaluated.
diff --git a/tvix/eval/src/vm.rs b/tvix/eval/src/vm.rs
index 127d9bfa513c..17a7e0ce2758 100644
--- a/tvix/eval/src/vm.rs
+++ b/tvix/eval/src/vm.rs
@@ -230,7 +230,10 @@ impl<'o> VM<'o> {
 
             Value::Builtin(b) => self.call_builtin(b.clone()),
 
-            Value::Thunk(t) => self.call_value(&t.value()),
+            Value::Thunk(t) => {
+                debug_assert!(t.is_evaluated(), "call_value called with unevaluated thunk");
+                self.call_value(&t.value())
+            }
 
             // Attribute sets with a __functor attribute are callable.
             Value::Attrs(ref attrs) => match attrs.select("__functor") {
@@ -277,6 +280,7 @@ impl<'o> VM<'o> {
         let mut res = self.pop();
 
         for _ in 0..(num_args - 1) {
+            res.force(self).map_err(|e| self.error(e))?;
             self.call_value(&res)?;
             res = self.pop();
         }