1
Fork 0

Some cleanups around EarlyDiagCtxt

All callers of EarlyDiagCtxt::early_error now emit a fatal error.
This commit is contained in:
bjorn3 2025-02-02 15:17:29 +00:00
parent 6dd75f0d68
commit d237378cd1
8 changed files with 26 additions and 40 deletions

View file

@ -1,7 +1,6 @@
use std::{env, error, fmt, fs, io}; use std::{env, error, fmt, fs, io};
use rustc_session::EarlyDiagCtxt; use rustc_session::EarlyDiagCtxt;
use rustc_span::ErrorGuaranteed;
/// Expands argfiles in command line arguments. /// Expands argfiles in command line arguments.
#[derive(Default)] #[derive(Default)]
@ -118,22 +117,22 @@ pub fn arg_expand_all(early_dcx: &EarlyDiagCtxt, at_args: &[String]) -> Vec<Stri
/// ///
/// This function is identical to [`env::args()`] except that it emits an error when it encounters /// This function is identical to [`env::args()`] except that it emits an error when it encounters
/// non-Unicode arguments instead of panicking. /// non-Unicode arguments instead of panicking.
pub fn raw_args(early_dcx: &EarlyDiagCtxt) -> Result<Vec<String>, ErrorGuaranteed> { pub fn raw_args(early_dcx: &EarlyDiagCtxt) -> Vec<String> {
let mut res = Ok(Vec::new()); let mut args = Vec::new();
let mut guar = Ok(());
for (i, arg) in env::args_os().enumerate() { for (i, arg) in env::args_os().enumerate() {
match arg.into_string() { match arg.into_string() {
Ok(arg) => { Ok(arg) => args.push(arg),
if let Ok(args) = &mut res {
args.push(arg);
}
}
Err(arg) => { Err(arg) => {
res = guar =
Err(early_dcx.early_err(format!("argument {i} is not valid Unicode: {arg:?}"))) Err(early_dcx.early_err(format!("argument {i} is not valid Unicode: {arg:?}")))
} }
} }
} }
res if let Err(guar) = guar {
guar.raise_fatal();
}
args
} }
#[derive(Debug)] #[derive(Debug)]

View file

@ -1212,9 +1212,9 @@ pub fn catch_fatal_errors<F: FnOnce() -> R, R>(f: F) -> Result<R, FatalError> {
/// Variant of `catch_fatal_errors` for the `interface::Result` return type /// Variant of `catch_fatal_errors` for the `interface::Result` return type
/// that also computes the exit code. /// that also computes the exit code.
pub fn catch_with_exit_code(f: impl FnOnce() -> interface::Result<()>) -> i32 { pub fn catch_with_exit_code(f: impl FnOnce()) -> i32 {
match catch_fatal_errors(f) { match catch_fatal_errors(f) {
Ok(Ok(())) => EXIT_SUCCESS, Ok(()) => EXIT_SUCCESS,
_ => EXIT_FAILURE, _ => EXIT_FAILURE,
} }
} }
@ -1499,10 +1499,8 @@ pub fn main() -> ! {
install_ice_hook(DEFAULT_BUG_REPORT_URL, |_| ()); install_ice_hook(DEFAULT_BUG_REPORT_URL, |_| ());
install_ctrlc_handler(); install_ctrlc_handler();
let exit_code = catch_with_exit_code(|| { let exit_code =
run_compiler(&args::raw_args(&early_dcx)?, &mut callbacks); catch_with_exit_code(|| run_compiler(&args::raw_args(&early_dcx), &mut callbacks));
Ok(())
});
if let Some(format) = callbacks.time_passes { if let Some(format) = callbacks.time_passes {
let end_rss = get_resident_set_size(); let end_rss = get_resident_set_size();

View file

@ -1819,7 +1819,7 @@ pub fn parse_error_format(
ErrorOutputType::HumanReadable(HumanReadableErrorType::Unicode, color) ErrorOutputType::HumanReadable(HumanReadableErrorType::Unicode, color)
} }
Some(arg) => { Some(arg) => {
early_dcx.abort_if_error_and_set_error_format(ErrorOutputType::HumanReadable( early_dcx.set_error_format(ErrorOutputType::HumanReadable(
HumanReadableErrorType::Default, HumanReadableErrorType::Default,
color, color,
)); ));
@ -2360,7 +2360,7 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M
let error_format = parse_error_format(early_dcx, matches, color, json_color, json_rendered); let error_format = parse_error_format(early_dcx, matches, color, json_color, json_rendered);
early_dcx.abort_if_error_and_set_error_format(error_format); early_dcx.set_error_format(error_format);
let diagnostic_width = matches.opt_get("diagnostic-width").unwrap_or_else(|_| { let diagnostic_width = matches.opt_get("diagnostic-width").unwrap_or_else(|_| {
early_dcx.early_fatal("`--diagnostic-width` must be an positive integer"); early_dcx.early_fatal("`--diagnostic-width` must be an positive integer");
@ -2770,6 +2770,7 @@ pub mod nightly_options {
"the option `{}` is only accepted on the nightly compiler", "the option `{}` is only accepted on the nightly compiler",
opt.name opt.name
); );
// The non-zero nightly_options_on_stable will force an early_fatal eventually.
let _ = early_dcx.early_err(msg); let _ = early_dcx.early_err(msg);
} }
OptionStability::Stable => {} OptionStability::Stable => {}

View file

@ -1362,12 +1362,6 @@ pub struct EarlyDiagCtxt {
dcx: DiagCtxt, dcx: DiagCtxt,
} }
impl Default for EarlyDiagCtxt {
fn default() -> Self {
Self::new(ErrorOutputType::default())
}
}
impl EarlyDiagCtxt { impl EarlyDiagCtxt {
pub fn new(output: ErrorOutputType) -> Self { pub fn new(output: ErrorOutputType) -> Self {
let emitter = mk_emitter(output); let emitter = mk_emitter(output);
@ -1375,10 +1369,9 @@ impl EarlyDiagCtxt {
} }
/// Swap out the underlying dcx once we acquire the user's preference on error emission /// Swap out the underlying dcx once we acquire the user's preference on error emission
/// format. Any errors prior to that will cause an abort and all stashed diagnostics of the /// format. If `early_err` was previously called this will panic.
/// previous dcx will be emitted. pub fn set_error_format(&mut self, output: ErrorOutputType) {
pub fn abort_if_error_and_set_error_format(&mut self, output: ErrorOutputType) { assert!(self.dcx.handle().has_errors().is_none());
self.dcx.handle().abort_if_errors();
let emitter = mk_emitter(output); let emitter = mk_emitter(output);
self.dcx = DiagCtxt::new(emitter); self.dcx = DiagCtxt::new(emitter);
@ -1398,7 +1391,7 @@ impl EarlyDiagCtxt {
#[allow(rustc::untranslatable_diagnostic)] #[allow(rustc::untranslatable_diagnostic)]
#[allow(rustc::diagnostic_outside_of_impl)] #[allow(rustc::diagnostic_outside_of_impl)]
#[must_use = "ErrorGuaranteed must be returned from `run_compiler` in order to exit with a non-zero status code"] #[must_use = "raise_fatal must be called on the returned ErrorGuaranteed in order to exit with a non-zero status code"]
pub fn early_err(&self, msg: impl Into<DiagMessage>) -> ErrorGuaranteed { pub fn early_err(&self, msg: impl Into<DiagMessage>) -> ErrorGuaranteed {
self.dcx.handle().err(msg) self.dcx.handle().err(msg)
} }

View file

@ -177,9 +177,8 @@ pub fn main() {
rustc_driver::init_logger(&early_dcx, rustc_log::LoggerConfig::from_env("RUSTDOC_LOG")); rustc_driver::init_logger(&early_dcx, rustc_log::LoggerConfig::from_env("RUSTDOC_LOG"));
let exit_code = rustc_driver::catch_with_exit_code(|| { let exit_code = rustc_driver::catch_with_exit_code(|| {
let at_args = rustc_driver::args::raw_args(&early_dcx)?; let at_args = rustc_driver::args::raw_args(&early_dcx);
main_args(&mut early_dcx, &at_args); main_args(&mut early_dcx, &at_args);
Ok(())
}); });
process::exit(exit_code); process::exit(exit_code);
} }

View file

@ -197,7 +197,7 @@ pub fn main() {
}); });
exit(rustc_driver::catch_with_exit_code(move || { exit(rustc_driver::catch_with_exit_code(move || {
let mut orig_args = rustc_driver::args::raw_args(&early_dcx)?; let mut orig_args = rustc_driver::args::raw_args(&early_dcx);
let has_sysroot_arg = |args: &mut [String]| -> bool { let has_sysroot_arg = |args: &mut [String]| -> bool {
if has_arg(args, "--sysroot") { if has_arg(args, "--sysroot") {
@ -239,7 +239,7 @@ pub fn main() {
pass_sysroot_env_if_given(&mut args, sys_root_env); pass_sysroot_env_if_given(&mut args, sys_root_env);
rustc_driver::run_compiler(&args, &mut DefaultCallbacks); rustc_driver::run_compiler(&args, &mut DefaultCallbacks);
return Ok(()); return;
} }
if orig_args.iter().any(|a| a == "--version" || a == "-V") { if orig_args.iter().any(|a| a == "--version" || a == "-V") {
@ -301,7 +301,6 @@ pub fn main() {
} else { } else {
rustc_driver::run_compiler(&args, &mut RustcCallbacks { clippy_args_var }); rustc_driver::run_compiler(&args, &mut RustcCallbacks { clippy_args_var });
} }
Ok(())
})) }))
} }

View file

@ -379,10 +379,8 @@ fn run_compiler_and_exit(
callbacks: &mut (dyn rustc_driver::Callbacks + Send), callbacks: &mut (dyn rustc_driver::Callbacks + Send),
) -> ! { ) -> ! {
// Invoke compiler, and handle return code. // Invoke compiler, and handle return code.
let exit_code = rustc_driver::catch_with_exit_code(move || { let exit_code =
rustc_driver::run_compiler(args, callbacks); rustc_driver::catch_with_exit_code(move || rustc_driver::run_compiler(args, callbacks));
Ok(())
});
std::process::exit(exit_code) std::process::exit(exit_code)
} }
@ -461,7 +459,7 @@ fn main() {
// (`install_ice_hook` might change `RUST_BACKTRACE`.) // (`install_ice_hook` might change `RUST_BACKTRACE`.)
let env_snapshot = env::vars_os().collect::<Vec<_>>(); let env_snapshot = env::vars_os().collect::<Vec<_>>();
let args = rustc_driver::args::raw_args(&early_dcx) let args = rustc_driver::catch_fatal_errors(|| rustc_driver::args::raw_args(&early_dcx))
.unwrap_or_else(|_| std::process::exit(rustc_driver::EXIT_FAILURE)); .unwrap_or_else(|_| std::process::exit(rustc_driver::EXIT_FAILURE));
// Install the ctrlc handler that sets `rustc_const_eval::CTRL_C_RECEIVED`, even if // Install the ctrlc handler that sets `rustc_const_eval::CTRL_C_RECEIVED`, even if

View file

@ -48,7 +48,6 @@ fn main() {
let mut callbacks = CompilerCalls::default(); let mut callbacks = CompilerCalls::default();
// Call the Rust compiler with our callbacks. // Call the Rust compiler with our callbacks.
rustc_driver::run_compiler(&rustc_args, &mut callbacks); rustc_driver::run_compiler(&rustc_args, &mut callbacks);
Ok(())
}); });
std::process::exit(exit_code); std::process::exit(exit_code);
} }