Rollup merge of #150379 - ChrisDenton:exitcode, r=jieyouxu
Return `ExitCode` from `rustc_driver::main` instead of calling `process::exit` This makes rustc simply return an exit code from main rather than calling `std::process::exit` with an exit code. This means that drops run normally and the process exits cleanly. This is similar to what happens when an ICE occurs (due to being a panic that's caught by std's `lang_start`). Also instead of hard coding success and failure codes this uses `ExitCode::SUCCESS` and `ExitCode::FAILURE`, which in turn effectively uses `libc::EXIT_SUCCESS` and `libc::EXIT_FAILURE` (via std). These are `0` and `1` respectively for all currently supported host platforms so it doesn't actually change the exit code.
This commit is contained in:
commit
c0b4db118b
7 changed files with 42 additions and 34 deletions
|
|
@ -3,6 +3,8 @@
|
|||
// Several crates are depended upon but unused so that they are present in the sysroot
|
||||
#![expect(unused_crate_dependencies)]
|
||||
|
||||
use std::process::ExitCode;
|
||||
|
||||
// A note about jemalloc: rustc uses jemalloc when built for CI and
|
||||
// distribution. The obvious way to do this is with the `#[global_allocator]`
|
||||
// mechanism. However, for complicated reasons (see
|
||||
|
|
@ -38,6 +40,6 @@
|
|||
#[cfg(feature = "jemalloc")]
|
||||
use tikv_jemalloc_sys as _;
|
||||
|
||||
fn main() {
|
||||
fn main() -> ExitCode {
|
||||
rustc_driver::main()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ use std::fs::{self, File};
|
|||
use std::io::{self, IsTerminal, Read, Write};
|
||||
use std::panic::{self, PanicHookInfo};
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::process::{self, Command, Stdio};
|
||||
use std::process::{Command, ExitCode, Stdio, Termination};
|
||||
use std::sync::OnceLock;
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
use std::time::Instant;
|
||||
|
|
@ -1404,10 +1404,10 @@ fn parse_crate_attrs<'a>(sess: &'a Session) -> PResult<'a, ast::AttrVec> {
|
|||
|
||||
/// Variant of `catch_fatal_errors` for the `interface::Result` return type
|
||||
/// that also computes the exit code.
|
||||
pub fn catch_with_exit_code(f: impl FnOnce()) -> i32 {
|
||||
pub fn catch_with_exit_code<T: Termination>(f: impl FnOnce() -> T) -> ExitCode {
|
||||
match catch_fatal_errors(f) {
|
||||
Ok(()) => EXIT_SUCCESS,
|
||||
_ => EXIT_FAILURE,
|
||||
Ok(status) => status.report(),
|
||||
_ => ExitCode::FAILURE,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1692,7 +1692,7 @@ pub fn install_ctrlc_handler() {
|
|||
.expect("Unable to install ctrlc handler");
|
||||
}
|
||||
|
||||
pub fn main() -> ! {
|
||||
pub fn main() -> ExitCode {
|
||||
let start_time = Instant::now();
|
||||
let start_rss = get_resident_set_size();
|
||||
|
||||
|
|
@ -1712,5 +1712,5 @@ pub fn main() -> ! {
|
|||
print_time_passes_entry("total", start_time.elapsed(), start_rss, end_rss, format);
|
||||
}
|
||||
|
||||
process::exit(exit_code)
|
||||
exit_code
|
||||
}
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ extern crate tikv_jemalloc_sys as _;
|
|||
use std::env::{self, VarError};
|
||||
use std::io::{self, IsTerminal};
|
||||
use std::path::Path;
|
||||
use std::process;
|
||||
use std::process::ExitCode;
|
||||
|
||||
use rustc_errors::DiagCtxtHandle;
|
||||
use rustc_hir::def_id::LOCAL_CRATE;
|
||||
|
|
@ -126,7 +126,7 @@ mod visit;
|
|||
mod visit_ast;
|
||||
mod visit_lib;
|
||||
|
||||
pub fn main() {
|
||||
pub fn main() -> ExitCode {
|
||||
let mut early_dcx = EarlyDiagCtxt::new(ErrorOutputType::default());
|
||||
|
||||
rustc_driver::install_ice_hook(
|
||||
|
|
@ -164,11 +164,10 @@ pub fn main() {
|
|||
Err(error) => early_dcx.early_fatal(error.to_string()),
|
||||
}
|
||||
|
||||
let exit_code = rustc_driver::catch_with_exit_code(|| {
|
||||
rustc_driver::catch_with_exit_code(|| {
|
||||
let at_args = rustc_driver::args::raw_args(&early_dcx);
|
||||
main_args(&mut early_dcx, &at_args);
|
||||
});
|
||||
process::exit(exit_code);
|
||||
})
|
||||
}
|
||||
|
||||
fn init_logging(early_dcx: &EarlyDiagCtxt) {
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ use std::env;
|
|||
use std::fs::read_to_string;
|
||||
use std::io::Write as _;
|
||||
use std::path::Path;
|
||||
use std::process::exit;
|
||||
use std::process::ExitCode;
|
||||
|
||||
/// If a command-line option matches `find_arg`, then apply the predicate `pred` on its value. If
|
||||
/// true, then return it. The parameter is assumed to be either `--arg=value` or `--arg value`.
|
||||
|
|
@ -182,15 +182,17 @@ impl rustc_driver::Callbacks for ClippyCallbacks {
|
|||
}
|
||||
}
|
||||
|
||||
fn display_help() {
|
||||
fn display_help() -> ExitCode {
|
||||
if writeln!(&mut anstream::stdout().lock(), "{}", help_message()).is_err() {
|
||||
exit(rustc_driver::EXIT_FAILURE);
|
||||
ExitCode::FAILURE
|
||||
} else {
|
||||
ExitCode::SUCCESS
|
||||
}
|
||||
}
|
||||
|
||||
const BUG_REPORT_URL: &str = "https://github.com/rust-lang/rust-clippy/issues/new?template=ice.yml";
|
||||
|
||||
pub fn main() {
|
||||
pub fn main() -> ExitCode {
|
||||
let early_dcx = EarlyDiagCtxt::new(ErrorOutputType::default());
|
||||
|
||||
rustc_driver::init_rustc_env_logger(&early_dcx);
|
||||
|
|
@ -203,7 +205,7 @@ pub fn main() {
|
|||
dcx.handle().note(format!("Clippy version: {version_info}"));
|
||||
});
|
||||
|
||||
exit(rustc_driver::catch_with_exit_code(move || {
|
||||
rustc_driver::catch_with_exit_code(move || {
|
||||
let mut orig_args = rustc_driver::args::raw_args(&early_dcx);
|
||||
|
||||
let has_sysroot_arg = |args: &mut [String]| -> bool {
|
||||
|
|
@ -246,15 +248,15 @@ pub fn main() {
|
|||
pass_sysroot_env_if_given(&mut args, sys_root_env);
|
||||
|
||||
rustc_driver::run_compiler(&args, &mut DefaultCallbacks);
|
||||
return;
|
||||
return ExitCode::SUCCESS;
|
||||
}
|
||||
|
||||
if orig_args.iter().any(|a| a == "--version" || a == "-V") {
|
||||
let version_info = rustc_tools_util::get_version_info!();
|
||||
|
||||
match writeln!(&mut anstream::stdout().lock(), "{version_info}") {
|
||||
Ok(()) => exit(rustc_driver::EXIT_SUCCESS),
|
||||
Err(_) => exit(rustc_driver::EXIT_FAILURE),
|
||||
return match writeln!(&mut anstream::stdout().lock(), "{version_info}") {
|
||||
Ok(()) => ExitCode::SUCCESS,
|
||||
Err(_) => ExitCode::FAILURE,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -268,8 +270,7 @@ pub fn main() {
|
|||
}
|
||||
|
||||
if !wrapper_mode && (orig_args.iter().any(|a| a == "--help" || a == "-h") || orig_args.len() == 1) {
|
||||
display_help();
|
||||
exit(0);
|
||||
return display_help();
|
||||
}
|
||||
|
||||
let mut args: Vec<String> = orig_args.clone();
|
||||
|
|
@ -311,7 +312,8 @@ pub fn main() {
|
|||
} else {
|
||||
rustc_driver::run_compiler(&args, &mut RustcCallbacks { clippy_args_var });
|
||||
}
|
||||
}))
|
||||
ExitCode::SUCCESS
|
||||
})
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ mod log;
|
|||
use std::env;
|
||||
use std::num::{NonZero, NonZeroI32};
|
||||
use std::ops::Range;
|
||||
use std::process::ExitCode;
|
||||
use std::rc::Rc;
|
||||
use std::str::FromStr;
|
||||
use std::sync::Once;
|
||||
|
|
@ -404,7 +405,11 @@ fn run_compiler_and_exit(
|
|||
// Invoke compiler, catch any unwinding panics and handle return code.
|
||||
let exit_code =
|
||||
rustc_driver::catch_with_exit_code(move || rustc_driver::run_compiler(args, callbacks));
|
||||
exit(exit_code)
|
||||
exit(if exit_code == ExitCode::SUCCESS {
|
||||
rustc_driver::EXIT_SUCCESS
|
||||
} else {
|
||||
rustc_driver::EXIT_FAILURE
|
||||
})
|
||||
}
|
||||
|
||||
/// Parses a comma separated list of `T` from the given string:
|
||||
|
|
@ -434,7 +439,7 @@ fn parse_range(val: &str) -> Result<Range<u32>, &'static str> {
|
|||
Ok(from..to)
|
||||
}
|
||||
|
||||
fn main() {
|
||||
fn main() -> ExitCode {
|
||||
let early_dcx = EarlyDiagCtxt::new(ErrorOutputType::default());
|
||||
|
||||
// Snapshot a copy of the environment before `rustc` starts messing with it.
|
||||
|
|
@ -449,9 +454,7 @@ fn main() {
|
|||
if crate_kind == "host" {
|
||||
// For host crates like proc macros and build scripts, we are an entirely normal rustc.
|
||||
// These eventually produce actual binaries and never run in Miri.
|
||||
match rustc_driver::main() {
|
||||
// Empty match proves this function will never return.
|
||||
}
|
||||
return rustc_driver::main();
|
||||
} else if crate_kind != "target" {
|
||||
panic!("invalid `MIRI_BE_RUSTC` value: {crate_kind:?}")
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
// We need this feature as it changes `dylib` linking behavior and allows us to link to `rustc_driver`.
|
||||
#![feature(rustc_private)]
|
||||
|
||||
fn main() {
|
||||
use std::process::ExitCode;
|
||||
|
||||
fn main() -> ExitCode {
|
||||
rustdoc::main()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ extern crate rustc_session;
|
|||
|
||||
use std::cell::RefCell;
|
||||
use std::collections::HashMap;
|
||||
use std::process::ExitCode;
|
||||
use std::thread_local;
|
||||
|
||||
use rustc_borrowck::consumers::{self, BodyWithBorrowckFacts, ConsumerOptions};
|
||||
|
|
@ -42,16 +43,15 @@ use rustc_middle::ty::TyCtxt;
|
|||
use rustc_middle::util::Providers;
|
||||
use rustc_session::Session;
|
||||
|
||||
fn main() {
|
||||
let exit_code = rustc_driver::catch_with_exit_code(move || {
|
||||
fn main() -> ExitCode {
|
||||
rustc_driver::catch_with_exit_code(move || {
|
||||
let mut rustc_args: Vec<_> = std::env::args().collect();
|
||||
// We must pass -Zpolonius so that the borrowck information is computed.
|
||||
rustc_args.push("-Zpolonius".to_owned());
|
||||
let mut callbacks = CompilerCalls::default();
|
||||
// Call the Rust compiler with our callbacks.
|
||||
rustc_driver::run_compiler(&rustc_args, &mut callbacks);
|
||||
});
|
||||
std::process::exit(exit_code);
|
||||
})
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue