diff --git a/tvix/eval/src/errors.rs b/tvix/eval/src/errors.rs index b3b45c6ce..8ecad8053 100644 --- a/tvix/eval/src/errors.rs +++ b/tvix/eval/src/errors.rs @@ -3,7 +3,7 @@ use std::path::PathBuf; use std::{fmt::Display, num::ParseIntError}; use codemap::{CodeMap, Span}; -use codemap_diagnostic::{Diagnostic, Emitter, Level, SpanLabel, SpanStyle}; +use codemap_diagnostic::{ColorConfig, Diagnostic, Emitter, Level, SpanLabel, SpanStyle}; use smol_str::SmolStr; use crate::Value; @@ -141,6 +141,12 @@ impl Error { String::from_utf8_lossy(&out).to_string() } + /// Render a fancy, human-readable output of this error and print + /// it to stderr. + pub fn fancy_format_stderr(&self, codemap: &CodeMap) { + Emitter::stderr(ColorConfig::Auto, Some(codemap)).emit(&[self.diagnostic(codemap)]); + } + /// Create the optional span label displayed as an annotation on /// the underlined span of the error. fn span_label(&self) -> Option { diff --git a/tvix/eval/src/eval.rs b/tvix/eval/src/eval.rs index 21591802a..e6199e00b 100644 --- a/tvix/eval/src/eval.rs +++ b/tvix/eval/src/eval.rs @@ -81,21 +81,22 @@ pub fn interpret(code: &str, location: Option, options: Options) -> Eva } for error in &result.errors { - eprintln!( - "compiler error: {:?} at `{}`[line {}]", - error.kind, - file.source_slice(error.span), - file.find_line(error.span.low()) + 1 - ); + error.fancy_format_stderr(&codemap); } if let Some(err) = result.errors.last() { return Err(err.clone()); } - if options.trace_runtime { + let result = if options.trace_runtime { crate::vm::run_lambda(&mut TracingObserver::new(std::io::stderr()), result.lambda) } else { crate::vm::run_lambda(&mut NoOpObserver::default(), result.lambda) + }; + + if let Err(err) = &result { + err.fancy_format_stderr(&codemap); } + + result } diff --git a/tvix/eval/src/main.rs b/tvix/eval/src/main.rs index 351554c2d..efd4d14c3 100644 --- a/tvix/eval/src/main.rs +++ b/tvix/eval/src/main.rs @@ -72,7 +72,7 @@ fn run_prompt(eval_options: tvix_eval::Options) { Ok(result) => { println!("=> {} :: {}", result, result.type_of()); } - Err(err) => println!("{}", err), + Err(_) => { /* interpret takes care of error formatting */ } } } Err(ReadlineError::Interrupted) | Err(ReadlineError::Eof) => break,