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 <grfn@gws.fyi>
Autosubmit: tazjin <tazjin@tvl.su>
Tested-by: BuildkiteCI
This commit is contained in:
Vincent Ambo 2022-10-11 01:04:19 +03:00 committed by clbot
parent 75f637c1f5
commit 019ea51e5c

View file

@ -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<Diagnostic> {
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)],
}
}
}