about summary refs log tree commit diff
path: root/tvix/eval/src/value/builtin.rs
diff options
context:
space:
mode:
authorsterni <sternenseemann@systemli.org>2022-09-18T22·48+0200
committersterni <sternenseemann@systemli.org>2022-09-19T09·58+0000
commitb79e248959cbccd6b387a52750de54b388a9a2c3 (patch)
treee2fb2ba89f779aa97888083333a8b2e71a06da0f /tvix/eval/src/value/builtin.rs
parentfefa8c55c45d82fc1d81e02a96e126812e1e1223 (diff)
refactor(tvix/eval): handle forcing in Builtin::apply r/4918
Instead of arity, we pass a array reference to Builtin::new that
describes how many arguments there are and which of them need to be
forced, eliminating the need to force manually.

Note that this change doesn't fix some of the instances where the the
Builtin doesn't consider that the value could be a Thunk.

Change-Id: Iadb58bb79886c30dc6b09dcf0ffad8abf28036a1
Reviewed-on: https://cl.tvl.fyi/c/depot/+/6662
Reviewed-by: tazjin <tazjin@tvl.su>
Tested-by: BuildkiteCI
Diffstat (limited to 'tvix/eval/src/value/builtin.rs')
-rw-r--r--tvix/eval/src/value/builtin.rs16
1 files changed, 12 insertions, 4 deletions
diff --git a/tvix/eval/src/value/builtin.rs b/tvix/eval/src/value/builtin.rs
index e79451392c2b..ca9924c5d5aa 100644
--- a/tvix/eval/src/value/builtin.rs
+++ b/tvix/eval/src/value/builtin.rs
@@ -36,7 +36,10 @@ pub type BuiltinFn = fn(arg: Vec<Value>, vm: &mut VM) -> Result<Value, ErrorKind
 #[derive(Clone)]
 pub struct Builtin {
     name: &'static str,
-    arity: usize,
+    /// Array reference that describes how many arguments there are (usually 1
+    /// or 2) and whether they need to be forced. `true` causes the
+    /// corresponding argument to be forced before `func` is called.
+    strict_args: &'static [bool],
     func: BuiltinFn,
 
     /// Partially applied function arguments.
@@ -44,10 +47,10 @@ pub struct Builtin {
 }
 
 impl Builtin {
-    pub fn new(name: &'static str, arity: usize, func: BuiltinFn) -> Self {
+    pub fn new(name: &'static str, strict_args: &'static [bool], func: BuiltinFn) -> Self {
         Builtin {
             name,
-            arity,
+            strict_args,
             func,
             partials: vec![],
         }
@@ -63,7 +66,12 @@ impl Builtin {
     pub fn apply(mut self, vm: &mut VM, arg: Value) -> Result<Value, ErrorKind> {
         self.partials.push(arg);
 
-        if self.partials.len() == self.arity {
+        if self.partials.len() == self.strict_args.len() {
+            for (idx, force) in self.strict_args.iter().enumerate() {
+                if *force {
+                    self.partials[idx].force(vm)?;
+                }
+            }
             return (self.func)(self.partials, vm);
         }