mirror of
https://github.com/rust-lang/rust.git
synced 2026-05-02 00:07:42 +03:00
42 lines
1.2 KiB
Rust
42 lines
1.2 KiB
Rust
/// Used as a return value to signify a fatal error occurred.
|
|
#[derive(Copy, Clone, Debug)]
|
|
#[must_use]
|
|
pub struct FatalError;
|
|
|
|
use std::panic;
|
|
|
|
pub use rustc_data_structures::FatalErrorMarker;
|
|
|
|
// Don't implement Send on FatalError. This makes it impossible to `panic_any!(FatalError)`.
|
|
// We don't want to invoke the panic handler and print a backtrace for fatal errors.
|
|
impl !Send for FatalError {}
|
|
|
|
impl FatalError {
|
|
pub fn raise(self) -> ! {
|
|
std::panic::resume_unwind(Box::new(FatalErrorMarker))
|
|
}
|
|
}
|
|
|
|
impl std::fmt::Display for FatalError {
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
write!(f, "fatal error")
|
|
}
|
|
}
|
|
|
|
impl std::error::Error for FatalError {}
|
|
|
|
/// Runs a closure and catches unwinds triggered by fatal errors.
|
|
///
|
|
/// The compiler currently unwinds with a special sentinel value to abort
|
|
/// compilation on fatal errors. This function catches that sentinel and turns
|
|
/// the panic into a `Result` instead.
|
|
pub fn catch_fatal_errors<F: FnOnce() -> R, R>(f: F) -> Result<R, FatalError> {
|
|
panic::catch_unwind(panic::AssertUnwindSafe(f)).map_err(|value| {
|
|
if value.is::<FatalErrorMarker>() {
|
|
FatalError
|
|
} else {
|
|
panic::resume_unwind(value);
|
|
}
|
|
})
|
|
}
|