about summary refs log tree commit diff
path: root/tvix/eval/src/value
diff options
context:
space:
mode:
Diffstat (limited to 'tvix/eval/src/value')
-rw-r--r--tvix/eval/src/value/attrs.rs14
-rw-r--r--tvix/eval/src/value/builtin.rs6
-rw-r--r--tvix/eval/src/value/mod.rs73
-rw-r--r--tvix/eval/src/value/thunk.rs10
4 files changed, 39 insertions, 64 deletions
diff --git a/tvix/eval/src/value/attrs.rs b/tvix/eval/src/value/attrs.rs
index 2954f8522097..d122f9155d2c 100644
--- a/tvix/eval/src/value/attrs.rs
+++ b/tvix/eval/src/value/attrs.rs
@@ -10,7 +10,7 @@ use std::collections::BTreeMap;
 use std::fmt::Display;
 use std::rc::Rc;
 
-use crate::errors::{ErrorKind, EvalResult};
+use crate::errors::ErrorKind;
 
 use super::string::NixString;
 use super::Value;
@@ -236,7 +236,7 @@ impl NixAttrs {
 
     /// Implement construction logic of an attribute set, to encapsulate
     /// logic about attribute set optimisations inside of this module.
-    pub fn construct(count: usize, mut stack_slice: Vec<Value>) -> EvalResult<Self> {
+    pub fn construct(count: usize, mut stack_slice: Vec<Value>) -> Result<Self, ErrorKind> {
         debug_assert!(
             stack_slice.len() == count * 2,
             "construct_attrs called with count == {}, but slice.len() == {}",
@@ -342,12 +342,11 @@ fn attempt_optimise_kv(slice: &mut [Value]) -> Option<NixAttrs> {
 
 // Set an attribute on an in-construction attribute set, while
 // checking against duplicate keys.
-fn set_attr(attrs: &mut NixAttrs, key: NixString, value: Value) -> EvalResult<()> {
+fn set_attr(attrs: &mut NixAttrs, key: NixString, value: Value) -> Result<(), ErrorKind> {
     match attrs.0.map_mut().entry(key) {
         btree_map::Entry::Occupied(entry) => Err(ErrorKind::DuplicateAttrsKey {
             key: entry.key().as_str().to_string(),
-        }
-        .into()),
+        }),
 
         btree_map::Entry::Vacant(entry) => {
             entry.insert(value);
@@ -367,7 +366,7 @@ fn set_nested_attr(
     key: NixString,
     mut path: Vec<NixString>,
     value: Value,
-) -> EvalResult<()> {
+) -> Result<(), ErrorKind> {
     // If there is no next key we are at the point where we
     // should insert the value itself.
     if path.is_empty() {
@@ -408,8 +407,7 @@ fn set_nested_attr(
             _ => {
                 return Err(ErrorKind::DuplicateAttrsKey {
                     key: entry.key().as_str().to_string(),
-                }
-                .into())
+                })
             }
         },
     }
diff --git a/tvix/eval/src/value/builtin.rs b/tvix/eval/src/value/builtin.rs
index e876c235557e..d1248b1ec219 100644
--- a/tvix/eval/src/value/builtin.rs
+++ b/tvix/eval/src/value/builtin.rs
@@ -3,13 +3,13 @@
 //!
 //! Builtins are directly backed by Rust code operating on Nix values.
 
-use crate::errors::EvalResult;
+use crate::errors::ErrorKind;
 
 use super::Value;
 
 use std::fmt::{Debug, Display};
 
-pub type BuiltinFn = fn(arg: Vec<Value>) -> EvalResult<Value>;
+pub type BuiltinFn = fn(arg: Vec<Value>) -> Result<Value, ErrorKind>;
 
 /// Represents a single built-in function which directly executes Rust
 /// code that operates on a Nix value.
@@ -50,7 +50,7 @@ impl Builtin {
     /// Apply an additional argument to the builtin, which will either
     /// lead to execution of the function or to returning a partial
     /// builtin.
-    pub fn apply(mut self, arg: Value) -> EvalResult<Value> {
+    pub fn apply(mut self, arg: Value) -> Result<Value, ErrorKind> {
         self.partials.push(arg);
 
         if self.partials.len() == self.arity {
diff --git a/tvix/eval/src/value/mod.rs b/tvix/eval/src/value/mod.rs
index a8bfc164cdf9..5cfad2e66ea8 100644
--- a/tvix/eval/src/value/mod.rs
+++ b/tvix/eval/src/value/mod.rs
@@ -10,7 +10,7 @@ mod list;
 mod string;
 mod thunk;
 
-use crate::errors::{ErrorKind, EvalResult};
+use crate::errors::ErrorKind;
 use crate::opcode::StackIdx;
 pub use attrs::NixAttrs;
 pub use builtin::Builtin;
@@ -70,91 +70,59 @@ impl Value {
         }
     }
 
-    pub fn as_bool(&self) -> EvalResult<bool> {
+    pub fn as_bool(&self) -> Result<bool, ErrorKind> {
         match self {
             Value::Bool(b) => Ok(*b),
-            other => Err(ErrorKind::TypeError {
-                expected: "bool",
-                actual: other.type_of(),
-            }
-            .into()),
+            other => Err(type_error("bool", &other)),
         }
     }
 
-    pub fn as_attrs(&self) -> EvalResult<&NixAttrs> {
+    pub fn as_attrs(&self) -> Result<&NixAttrs, ErrorKind> {
         match self {
             Value::Attrs(attrs) => Ok(attrs),
-            other => Err(ErrorKind::TypeError {
-                expected: "set",
-                actual: other.type_of(),
-            }
-            .into()),
+            other => Err(type_error("set", &other)),
         }
     }
 
-    pub fn as_str(&self) -> EvalResult<&str> {
+    pub fn as_str(&self) -> Result<&str, ErrorKind> {
         match self {
             Value::String(s) => Ok(s.as_str()),
-            other => Err(ErrorKind::TypeError {
-                expected: "string",
-                actual: other.type_of(),
-            }
-            .into()),
+            other => Err(type_error("string", &other)),
         }
     }
 
-    pub fn as_list(&self) -> EvalResult<&NixList> {
+    pub fn as_list(&self) -> Result<&NixList, ErrorKind> {
         match self {
             Value::List(xs) => Ok(xs),
-            other => Err(ErrorKind::TypeError {
-                expected: "list",
-                actual: other.type_of(),
-            }
-            .into()),
+            other => Err(type_error("list", &other)),
         }
     }
 
-    pub fn to_string(self) -> EvalResult<NixString> {
+    pub fn to_string(self) -> Result<NixString, ErrorKind> {
         match self {
             Value::String(s) => Ok(s),
-            other => Err(ErrorKind::TypeError {
-                expected: "string",
-                actual: other.type_of(),
-            }
-            .into()),
+            other => Err(type_error("string", &other)),
         }
     }
 
-    pub fn to_attrs(self) -> EvalResult<Rc<NixAttrs>> {
+    pub fn to_attrs(self) -> Result<Rc<NixAttrs>, ErrorKind> {
         match self {
             Value::Attrs(s) => Ok(s),
-            other => Err(ErrorKind::TypeError {
-                expected: "set",
-                actual: other.type_of(),
-            }
-            .into()),
+            other => Err(type_error("set", &other)),
         }
     }
 
-    pub fn to_list(self) -> EvalResult<NixList> {
+    pub fn to_list(self) -> Result<NixList, ErrorKind> {
         match self {
             Value::List(l) => Ok(l),
-            other => Err(ErrorKind::TypeError {
-                expected: "list",
-                actual: other.type_of(),
-            }
-            .into()),
+            other => Err(type_error("list", &other)),
         }
     }
 
-    pub fn to_closure(self) -> EvalResult<Closure> {
+    pub fn to_closure(self) -> Result<Closure, ErrorKind> {
         match self {
             Value::Closure(c) => Ok(c),
-            other => Err(ErrorKind::TypeError {
-                expected: "lambda",
-                actual: other.type_of(),
-            }
-            .into()),
+            other => Err(type_error("lambda", &other)),
         }
     }
 
@@ -231,3 +199,10 @@ impl PartialEq for Value {
         }
     }
 }
+
+fn type_error(expected: &'static str, actual: &Value) -> ErrorKind {
+    ErrorKind::TypeError {
+        expected,
+        actual: actual.type_of(),
+    }
+}
diff --git a/tvix/eval/src/value/thunk.rs b/tvix/eval/src/value/thunk.rs
index 307eb23a75f6..c2552284fe20 100644
--- a/tvix/eval/src/value/thunk.rs
+++ b/tvix/eval/src/value/thunk.rs
@@ -24,7 +24,7 @@ use std::{
     rc::Rc,
 };
 
-use crate::{errors::ErrorKind, upvalues::UpvalueCarrier, vm::VM, EvalResult, Value};
+use crate::{errors::ErrorKind, upvalues::UpvalueCarrier, vm::VM, Value};
 
 use super::Lambda;
 
@@ -64,7 +64,7 @@ impl Thunk {
     /// to it, providing memoization) through interior mutability. In
     /// case of nested thunks, the intermediate thunk representations
     /// are replaced.
-    pub fn force(&self, vm: &mut VM) -> EvalResult<()> {
+    pub fn force(&self, vm: &mut VM) -> Result<(), ErrorKind> {
         // Due to mutable borrowing rules, the following code can't
         // easily use a match statement or something like that; it
         // requires a bit of manual fiddling.
@@ -78,14 +78,16 @@ impl Thunk {
                 }
 
                 ThunkRepr::Evaluated(_) => return Ok(()),
-                ThunkRepr::Blackhole => return Err(ErrorKind::InfiniteRecursion.into()),
+                ThunkRepr::Blackhole => return Err(ErrorKind::InfiniteRecursion),
 
                 ThunkRepr::Suspended { .. } => {
                     if let ThunkRepr::Suspended { lambda, upvalues } =
                         std::mem::replace(&mut *thunk_mut, ThunkRepr::Blackhole)
                     {
                         vm.call(lambda, upvalues, 0);
-                        *thunk_mut = ThunkRepr::Evaluated(vm.run()?);
+                        // TODO: find a cheap way to actually retain
+                        // the original error span
+                        *thunk_mut = ThunkRepr::Evaluated(vm.run().map_err(|e| e.kind)?);
                     }
                 }
             }