about summary refs log tree commit diff
path: root/tvix/eval/src/vm.rs
diff options
context:
space:
mode:
authorVincent Ambo <mail@tazj.in>2022-08-22T20·20+0300
committertazjin <tazjin@tvl.su>2022-09-01T21·40+0000
commit2662376941367d88687b3ebc4e4b941b266cee42 (patch)
tree9202de6ecebcb9d03e7940d0ddf8227f6a4ef1e1 /tvix/eval/src/vm.rs
parent51be6542c98158feb89e0e2d89f6b5165a070914 (diff)
feat(tvix/eval): carry optional SyntaxNode in error type r/4571
This starts paving the way for nicer, source-code based error
reporting.

Right now the code paths in the VM do not emit annotated errors, as we
do not yet preserve that structure from the compiler. However, error
emitting code paths in the compiler have been amended to include known
nodes.

Change-Id: I1b74410ffd891c40cd913361bd73c4336ec8aa5b
Reviewed-on: https://cl.tvl.fyi/c/depot/+/6235
Tested-by: BuildkiteCI
Reviewed-by: grfn <grfn@gws.fyi>
Diffstat (limited to 'tvix/eval/src/vm.rs')
-rw-r--r--tvix/eval/src/vm.rs29
1 files changed, 16 insertions, 13 deletions
diff --git a/tvix/eval/src/vm.rs b/tvix/eval/src/vm.rs
index cf70fda307..7a6a6454ea 100644
--- a/tvix/eval/src/vm.rs
+++ b/tvix/eval/src/vm.rs
@@ -5,7 +5,7 @@ use std::rc::Rc;
 
 use crate::{
     chunk::Chunk,
-    errors::{Error, EvalResult},
+    errors::{ErrorKind, EvalResult},
     opcode::OpCode,
     value::{NixAttrs, NixList, Value},
 };
@@ -38,14 +38,14 @@ macro_rules! arithmetic_op {
             (Value::Integer(i1), Value::Float(f2)) => Value::Float(i1 as f64 $op f2),
             (Value::Float(f1), Value::Integer(i2)) => Value::Float(f1 $op i2 as f64),
 
-            (v1, v2) => return Err(Error::TypeError {
+            (v1, v2) => return Err(ErrorKind::TypeError {
                 expected: "number (either int or float)",
                 actual: if v1.is_number() {
                     v2.type_of()
                 } else {
                     v1.type_of()
                 },
-            }),
+            }.into()),
         }
     }};
 }
@@ -65,10 +65,10 @@ macro_rules! cmp_op {
             (Value::Float(f1), Value::Integer(i2)) => f1 $op (i2 as f64),
             (Value::String(s1), Value::String(s2)) => s1 $op s2,
 
-            (lhs, rhs) => return Err(Error::Incomparable {
+            (lhs, rhs) => return Err(ErrorKind::Incomparable {
                 lhs: lhs.type_of(),
                 rhs: rhs.type_of(),
-            }),
+            }.into()),
         };
 
         $self.push(Value::Bool(result));
@@ -136,10 +136,11 @@ impl VM {
                     Value::Integer(i) => self.push(Value::Integer(-i)),
                     Value::Float(f) => self.push(Value::Float(-f)),
                     v => {
-                        return Err(Error::TypeError {
+                        return Err(ErrorKind::TypeError {
                             expected: "number (either int or float)",
                             actual: v.type_of(),
-                        })
+                        }
+                        .into())
                     }
                 },
 
@@ -177,9 +178,10 @@ impl VM {
                         Some(value) => self.push(value.clone()),
 
                         None => {
-                            return Err(Error::AttributeNotFound {
+                            return Err(ErrorKind::AttributeNotFound {
                                 name: key.as_str().to_string(),
-                            })
+                            }
+                            .into())
                         }
                     }
                 }
@@ -255,10 +257,11 @@ impl VM {
                 OpCode::OpAssertBool => {
                     let val = self.peek(0);
                     if !val.is_bool() {
-                        return Err(Error::TypeError {
+                        return Err(ErrorKind::TypeError {
                             expected: "bool",
                             actual: val.type_of(),
-                        });
+                        }
+                        .into());
                     }
                 }
 
@@ -302,12 +305,12 @@ impl VM {
                         }
                     }
 
-                    return Err(Error::UnknownDynamicVariable(ident.to_string()));
+                    return Err(ErrorKind::UnknownDynamicVariable(ident.to_string()).into());
                 }
 
                 OpCode::OpAssert => {
                     if !self.pop().as_bool()? {
-                        return Err(Error::AssertionFailed);
+                        return Err(ErrorKind::AssertionFailed.into());
                     }
                 }
             }