1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
//! 标准库中的 Panic 支持。

#![stable(feature = "core_panic_info", since = "1.41.0")]

mod location;
mod panic_info;
mod unwind_safe;

use crate::any::Any;

#[stable(feature = "panic_hooks", since = "1.10.0")]
pub use self::location::Location;
#[stable(feature = "panic_hooks", since = "1.10.0")]
pub use self::panic_info::PanicInfo;
#[stable(feature = "catch_unwind", since = "1.9.0")]
pub use self::unwind_safe::{AssertUnwindSafe, RefUnwindSafe, UnwindSafe};

#[doc(hidden)]
#[unstable(feature = "edition_panic", issue = "none", reason = "use panic!() instead")]
#[allow_internal_unstable(core_panic, const_format_args)]
#[rustc_diagnostic_item = "core_panic_2015_macro"]
#[rustc_macro_transparency = "semitransparent"]
pub macro panic_2015 {
    () => (
        $crate::panicking::panic("explicit panic")
    ),
    ($msg:literal $(,)?) => (
        $crate::panicking::panic($msg)
    ),
    // 对于 non_fmt_panic lint,使用 `panic_str` 而不是 `panic_display::<&str>`。
    ($msg:expr $(,)?) => (
        $crate::panicking::panic_str($msg)
    ),
    // 特殊情况下 const_panic 的单个参数情况。
    ("{}", $arg:expr $(,)?) => (
        $crate::panicking::panic_display(&$arg)
    ),
    ($fmt:expr, $($arg:tt)+) => (
        $crate::panicking::panic_fmt($crate::const_format_args!($fmt, $($arg)+))
    ),
}

#[doc(hidden)]
#[unstable(feature = "edition_panic", issue = "none", reason = "use panic!() instead")]
#[allow_internal_unstable(core_panic, const_format_args)]
#[rustc_diagnostic_item = "core_panic_2021_macro"]
#[rustc_macro_transparency = "semitransparent"]
pub macro panic_2021 {
    () => (
        $crate::panicking::panic("explicit panic")
    ),
    // 特殊情况下 const_panic 的单个参数情况。
    ("{}", $arg:expr $(,)?) => (
        $crate::panicking::panic_display(&$arg)
    ),
    ($($t:tt)+) => (
        $crate::panicking::panic_fmt($crate::const_format_args!($($t)+))
    ),
}

#[doc(hidden)]
#[unstable(feature = "edition_panic", issue = "none", reason = "use unreachable!() instead")]
#[allow_internal_unstable(core_panic)]
#[rustc_diagnostic_item = "unreachable_2015_macro"]
#[rustc_macro_transparency = "semitransparent"]
pub macro unreachable_2015 {
    () => (
        $crate::panicking::panic("internal error: entered unreachable code")
    ),
    // 将 `unreachable_display` 用于 non_fmt_panic lint。
    // NOTE: 消息 ("internal error ...") 直接嵌入到 unreachable_display
    ($msg:expr $(,)?) => (
        $crate::panicking::unreachable_display(&$msg)
    ),
    ($fmt:expr, $($arg:tt)*) => (
        $crate::panic!($crate::concat!("internal error: entered unreachable code: ", $fmt), $($arg)*)
    ),
}

#[doc(hidden)]
#[unstable(feature = "edition_panic", issue = "none", reason = "use unreachable!() instead")]
#[allow_internal_unstable(core_panic)]
#[rustc_diagnostic_item = "unreachable_2021_macro"]
#[rustc_macro_transparency = "semitransparent"]
pub macro unreachable_2021 {
    () => (
        $crate::panicking::panic("internal error: entered unreachable code")
    ),
    ($($t:tt)+) => (
        $crate::panic!("internal error: entered unreachable code: {}", $crate::format_args!($($t)+))
    ),
}

/// libstd 使用的内部 trait 将数据从 libstd 传递到 `panic_unwind` 和其他 panic 运行时。
/// 不打算在任何时候稳定下来,请勿使用。
///
#[unstable(feature = "std_internals", issue = "none")]
#[doc(hidden)]
pub unsafe trait BoxMeUp {
    /// 拥有内容的全部所有权。
    /// 返回类型实际上是 `Box<dyn Any + Send>`,但是我们不能在 libcore 中使用 `Box`。
    ///
    /// 调用此方法后,`self` 中仅保留一些虚拟默认值。
    /// 两次调用此方法,或在调用此方法后调用 `get`,都是错误的。
    ///
    /// 之所以借用该参数是因为 panic 运行时 (`__rust_start_panic`) 仅得到借用的 `dyn BoxMeUp`。
    ///
    fn take_box(&mut self) -> *mut (dyn Any + Send);

    /// 只是借用内容。
    fn get(&mut self) -> &(dyn Any + Send);
}