about summary refs log tree commit diff
path: root/tvix
diff options
context:
space:
mode:
Diffstat (limited to 'tvix')
-rw-r--r--tvix/eval/src/builtins/impure.rs8
-rw-r--r--tvix/eval/src/eval.rs8
-rw-r--r--tvix/eval/src/vm.rs36
3 files changed, 45 insertions, 7 deletions
diff --git a/tvix/eval/src/builtins/impure.rs b/tvix/eval/src/builtins/impure.rs
index 7c98fcb4e1..d73e5ccfa8 100644
--- a/tvix/eval/src/builtins/impure.rs
+++ b/tvix/eval/src/builtins/impure.rs
@@ -51,7 +51,7 @@ pub fn builtins_import(
     Builtin::new(
         "import",
         &[true],
-        move |mut args: Vec<Value>, _: &mut VM| {
+        move |mut args: Vec<Value>, vm: &mut VM| {
             let path = match args.pop().unwrap() {
                 Value::Path(path) => path,
                 Value::String(_) => {
@@ -102,9 +102,9 @@ pub fn builtins_import(
                 });
             }
 
-            // TODO: deal with runtime *warnings* (most likely through an
-            // emit_warning function on the VM that might return it together with
-            // the result)
+            for warning in result.warnings {
+                vm.push_warning(warning);
+            }
 
             // Compilation succeeded, we can construct a thunk from whatever it spat
             // out and return that.
diff --git a/tvix/eval/src/eval.rs b/tvix/eval/src/eval.rs
index 4e50b7279c..5af5f9d758 100644
--- a/tvix/eval/src/eval.rs
+++ b/tvix/eval/src/eval.rs
@@ -115,5 +115,11 @@ pub fn interpret(code: &str, location: Option<PathBuf>, options: Options) -> Eva
         err.fancy_format_stderr(&source);
     }
 
-    result
+    result.map(|r| {
+        for warning in r.warnings {
+            warning.fancy_format_stderr(&source);
+        }
+
+        r.value
+    })
 }
diff --git a/tvix/eval/src/vm.rs b/tvix/eval/src/vm.rs
index 41f51a9874..d616b9ce1c 100644
--- a/tvix/eval/src/vm.rs
+++ b/tvix/eval/src/vm.rs
@@ -10,6 +10,7 @@ use crate::{
     opcode::{CodeIdx, Count, JumpOffset, OpCode, StackIdx, UpvalueIdx},
     upvalues::{UpvalueCarrier, Upvalues},
     value::{Builtin, Closure, CoercionKind, Lambda, NixAttrs, NixList, Thunk, Value},
+    warnings::{EvalWarning, WarningKind},
 };
 
 struct CallFrame {
@@ -43,9 +44,18 @@ pub struct VM<'o> {
     /// dynamically resolved (`with`).
     with_stack: Vec<usize>,
 
+    /// Runtime warnings collected during evaluation.
+    warnings: Vec<EvalWarning>,
+
     observer: &'o mut dyn RuntimeObserver,
 }
 
+/// The result of a VM's runtime evaluation.
+pub struct RuntimeResult {
+    pub value: Value,
+    pub warnings: Vec<EvalWarning>,
+}
+
 /// This macro wraps a computation that returns an ErrorKind or a
 /// result, and wraps the ErrorKind in an Error struct if present.
 ///
@@ -133,6 +143,7 @@ impl<'o> VM<'o> {
             frames: vec![],
             stack: vec![],
             with_stack: vec![],
+            warnings: vec![],
         }
     }
 
@@ -182,6 +193,20 @@ impl<'o> VM<'o> {
         }
     }
 
+    /// Push an already constructed warning.
+    pub fn push_warning(&mut self, warning: EvalWarning) {
+        self.warnings.push(warning);
+    }
+
+    /// Emit a warning with the given WarningKind and the source span
+    /// of the current instruction.
+    pub fn emit_warning(&mut self, kind: WarningKind) {
+        self.push_warning(EvalWarning {
+            kind,
+            span: self.current_span(),
+        });
+    }
+
     /// Execute the given value in this VM's context, if it is a
     /// callable.
     ///
@@ -780,9 +805,16 @@ fn unwrap_or_clone_rc<T: Clone>(rc: Rc<T>) -> T {
     Rc::try_unwrap(rc).unwrap_or_else(|rc| (*rc).clone())
 }
 
-pub fn run_lambda(observer: &mut dyn RuntimeObserver, lambda: Rc<Lambda>) -> EvalResult<Value> {
+pub fn run_lambda(
+    observer: &mut dyn RuntimeObserver,
+    lambda: Rc<Lambda>,
+) -> EvalResult<RuntimeResult> {
     let mut vm = VM::new(observer);
     let value = vm.call(lambda, Upvalues::with_capacity(0), 0)?;
     vm.force_for_output(&value)?;
-    Ok(value)
+
+    Ok(RuntimeResult {
+        value,
+        warnings: vm.warnings,
+    })
 }