From 019ea51e5c7777d49fa835260b7ce62d77430b3b Mon Sep 17 00:00:00 2001 From: Vincent Ambo Date: Tue, 11 Oct 2022 01:04:19 +0300 Subject: fix(tvix/eval): format nested compiler errors in fancy output Instead of just printing the number of errors (useless!) actually emit separate diagnostics for each nested error. Change-Id: I97b53c3276c906af5def89077b5b6ba6ec108b37 Reviewed-on: https://cl.tvl.fyi/c/depot/+/6933 Reviewed-by: grfn Autosubmit: tazjin Tested-by: BuildkiteCI --- tvix/eval/src/errors.rs | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) (limited to 'tvix/eval/src') diff --git a/tvix/eval/src/errors.rs b/tvix/eval/src/errors.rs index 3986640beb..543ae7d41e 100644 --- a/tvix/eval/src/errors.rs +++ b/tvix/eval/src/errors.rs @@ -320,15 +320,10 @@ to a missing value in the attribute set(s) included via `with`."#, ) } - ErrorKind::ImportCompilerError { errors, path } => { - // TODO: chain display of these errors, though this is - // probably not the right place for that (should - // branch into a more elaborate diagnostic() call - // below). - write!( + ErrorKind::ImportCompilerError { path, .. } => { + writeln!( f, - "{} errors occured while importing '{}'", - errors.len(), + "compiler errors occured while importing '{}'", path.to_string_lossy() ) } @@ -572,7 +567,7 @@ fn spans_for_parse_errors(file: &File, errors: &[rnix::parser::ParseError]) -> V impl Error { pub fn fancy_format_str(&self, source: &SourceCode) -> String { let mut out = vec![]; - Emitter::vec(&mut out, Some(&*source.codemap())).emit(&[self.diagnostic(source)]); + Emitter::vec(&mut out, Some(&*source.codemap())).emit(&self.diagnostics(source)); String::from_utf8_lossy(&out).to_string() } @@ -580,7 +575,7 @@ impl Error { /// it to stderr. pub fn fancy_format_stderr(&self, source: &SourceCode) { Emitter::stderr(ColorConfig::Auto, Some(&*source.codemap())) - .emit(&[self.diagnostic(source)]); + .emit(&self.diagnostics(source)); } /// Create the optional span label displayed as an annotation on @@ -713,6 +708,7 @@ impl Error { } } + /// Create the primary diagnostic for a given error. fn diagnostic(&self, source: &SourceCode) -> Diagnostic { Diagnostic { level: Level::Error, @@ -721,4 +717,20 @@ impl Error { code: Some(self.code().into()), } } + + /// Return the primary diagnostic and all further associated diagnostics (if + /// any) of an error. + fn diagnostics(&self, source: &SourceCode) -> Vec { + match &self.kind { + ErrorKind::ThunkForce(err) => err.diagnostics(source), + + ErrorKind::ImportCompilerError { errors, .. } => { + let mut out = vec![self.diagnostic(source)]; + out.extend(errors.iter().map(|e| e.diagnostic(source))); + out + } + + _ => vec![self.diagnostic(source)], + } + } } -- cgit 1.4.1