diff --git a/cli/src/bin/naga.rs b/cli/src/bin/naga.rs index b121dd52db..e146c60ed7 100644 --- a/cli/src/bin/naga.rs +++ b/cli/src/bin/naga.rs @@ -1,7 +1,13 @@ #![allow(clippy::manual_strip)] #[allow(unused_imports)] use std::fs; -use std::{error::Error, fmt, io::Read, path::Path, str::FromStr}; +use std::{ + error::Error, + fmt, + io::{stderr, Read, Write}, + path::Path, + str::FromStr, +}; /// Translate shaders to different formats. #[derive(argh::FromArgs, Debug, Clone)] @@ -161,18 +167,18 @@ trait PrettyResult { fn unwrap_pretty(self) -> Self::Target; } -fn print_err(error: &dyn Error) { - eprint!("{error}"); +fn print_err(out: &mut dyn Write, error: &dyn Error) { + write!(out, "{error}").unwrap(); let mut e = error.source(); if e.is_some() { - eprintln!(": "); + writeln!(out, ":").unwrap(); } else { - eprintln!(); + writeln!(out).unwrap(); } while let Some(source) = e { - eprintln!("\t{source}"); + writeln!(out, " {source}").unwrap(); e = source.source(); } } @@ -183,7 +189,7 @@ impl PrettyResult for Result { match self { Result::Ok(value) => value, Result::Err(error) => { - print_err(&error); + print_err(&mut stderr().lock(), &error); std::process::exit(1); } } @@ -192,7 +198,7 @@ impl PrettyResult for Result { fn main() { if let Err(e) = run() { - print_err(e.as_ref()); + print_err(&mut stderr().lock(), e.as_ref()); std::process::exit(1); } } @@ -339,8 +345,9 @@ fn run() -> Result<(), Box> { if let Some(input) = input_text { let filename = input_path.file_name().and_then(std::ffi::OsStr::to_str); emit_annotated_error(&error, filename.unwrap_or("input"), &input); + } else { + print_err(&mut stderr().lock(), &error); } - print_err(&error); None } }; @@ -362,8 +369,6 @@ fn run() -> Result<(), Box> { .ok_or(CliError("Output filename not valid unicode"))? { "txt" => { - use std::io::Write; - let mut file = fs::File::create(output_path)?; writeln!(file, "{module:#?}")?; if let Some(ref info) = info { @@ -553,7 +558,14 @@ pub fn emit_annotated_error(ann_err: &WithSpan, filename: &str, sou let config = codespan_reporting::term::Config::default(); let writer = StandardStream::stderr(ColorChoice::Auto); - let diagnostic = Diagnostic::error().with_labels( + let mut msg_buf = Vec::new(); + print_err(&mut msg_buf, ann_err); + let msg = String::from_utf8(msg_buf) + .unwrap() + // NOTE: `replace` is intended to correct the alignment of multi-line messages against the + // `error: ` prefix, which is 7 characters. + .replace('\n', "\n "); + let diagnostic = Diagnostic::error().with_message(msg).with_labels( ann_err .spans() .map(|(span, desc)| { diff --git a/src/valid/mod.rs b/src/valid/mod.rs index 2c83e1a8d7..0b68c24c67 100644 --- a/src/valid/mod.rs +++ b/src/valid/mod.rs @@ -211,7 +211,7 @@ pub enum ValidationError { name: String, source: FunctionError, }, - #[error("Entry point {name} at {stage:?} is invalid")] + #[error("Entry point '{name}' at {stage:?} is invalid")] EntryPoint { stage: crate::ShaderStage, name: String,