Files
alloc
core
alloc
array
char
convert
fmt
future
hash
iter
macros
mem
num
ops
panic
portable-simd
prelude
ptr
slice
stdarch
str
stream
sync
task
unicode
std
backtrace
collections
ffi
io
net
os
prelude
sync
sys
sys_common
thread
time
  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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
//! 标准库中的 Panic 支持。

#![stable(feature = "std_panic", since = "1.9.0")]

use crate::any::Any;
use crate::collections;
use crate::panicking;
use crate::sync::{Mutex, RwLock};
use crate::thread::Result;

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

#[doc(hidden)]
#[unstable(feature = "edition_panic", issue = "none", reason = "use panic!() instead")]
pub use core::panic::panic_2021;

#[stable(feature = "panic_hooks", since = "1.10.0")]
pub use crate::panicking::{set_hook, take_hook};

#[stable(feature = "panic_hooks", since = "1.10.0")]
pub use core::panic::{Location, PanicInfo};

#[stable(feature = "catch_unwind", since = "1.9.0")]
pub use core::panic::{AssertUnwindSafe, RefUnwindSafe, UnwindSafe};

/// 使用给定的消息作为 panic 有效载荷,使当前线程 panic。
///
/// 该消息可以是任何 (`Any + Send`) 类型,而不仅仅是字符串。
///
/// 该消息包装在一个 `Box<'static + Any + Send>` 中,以后可以使用 [`PanicInfo::payload`] 访问它。
///
///
/// 有关 panic 的更多信息,请参见 [`panic!`] 宏。
#[stable(feature = "panic_any", since = "1.51.0")]
#[inline]
#[track_caller]
pub fn panic_any<M: 'static + Any + Send>(msg: M) -> ! {
    crate::panicking::begin_panic(msg);
}

#[stable(feature = "catch_unwind", since = "1.9.0")]
impl<T: ?Sized> UnwindSafe for Mutex<T> {}
#[stable(feature = "catch_unwind", since = "1.9.0")]
impl<T: ?Sized> UnwindSafe for RwLock<T> {}

#[stable(feature = "unwind_safe_lock_refs", since = "1.12.0")]
impl<T: ?Sized> RefUnwindSafe for Mutex<T> {}
#[stable(feature = "unwind_safe_lock_refs", since = "1.12.0")]
impl<T: ?Sized> RefUnwindSafe for RwLock<T> {}

// https://github.com/rust-lang/rust/issues/62301
#[stable(feature = "hashbrown", since = "1.36.0")]
impl<K, V, S> UnwindSafe for collections::HashMap<K, V, S>
where
    K: UnwindSafe,
    V: UnwindSafe,
    S: UnwindSafe,
{
}

/// 调用一个闭包,如果发生,则捕获展开 panic 的原因。
///
/// 如果闭包不是 panic,则此函数将返回 `Ok`,并返回闭包的结果; 如果闭包 panics,则此函数将返回 `Err(cause)`。
/// 返回的 `cause` 是最初调用 panic 的对象。
///
/// unwind 当前从 Rust 代码转换为外来代码是未定义的行为,因此当从另一种语言 (通常为 C) 调用 Rust 时,此函数特别有用。
/// 这可以运行任意的 Rust 代码,捕获 panic 并允许对错误进行适当的处理。
///
/// 不建议将此函数用于一般的 try/catch 机制。[`Result`] 类型更适合用于经常失败的函数。
/// 此外,不能保证此函数可以捕获所有 panics,请参见下面的 "Notes" 部分。
///
/// 提供的闭包必须遵守 [`UnwindSafe`] trait,以确保所有捕获的变量都可以安全越过此边界。
/// 此绑定的目的是在类型系统中对 [异常安全][rfc] 的概念进行编码。
/// 此函数的大多数用法都不必担心此绑定,因为没有 `unsafe` 代码的程序自然是 unwind 安全的。
/// 如果出现问题,可以使用 [`AssertUnwindSafe`] 包装器结构体快速断言此处的使用确实是 unwind 安全的。
///
/// [rfc]: https://github.com/rust-lang/rfcs/blob/master/text/1236-stabilize-catch-panic.md
///
/// # Notes
///
/// 请注意,此函数**可能无法捕获 Rust 中的所有 panics**。Rust 中的 panic 并不总是通过展开来实现,但是也可以通过中止进程来实现。
///
/// 该函数 *仅* 捕获展开 panics,而不是终止进程的 panics。
///
/// 另请注意,使用外部异常 (例如,展开为 Rust 代码)
/// 从 C++ 代码引发的异常) 是未定义的行为。
///
/// # Examples
///
/// ```
/// use std::panic;
///
/// let result = panic::catch_unwind(|| {
///     println!("hello!");
/// });
/// assert!(result.is_ok());
///
/// let result = panic::catch_unwind(|| {
///     panic!("oh no!");
/// });
/// assert!(result.is_err());
/// ```
///
///
///
///
///
///
///
///
///
#[stable(feature = "catch_unwind", since = "1.9.0")]
pub fn catch_unwind<F: FnOnce() -> R + UnwindSafe, R>(f: F) -> Result<R> {
    unsafe { panicking::r#try(f) }
}

/// 在不调用 panic 钩子的情况下触发 panic。
///
/// 它被设计为与 [`catch_unwind`] 结合使用,例如,跨 C 代码层携带 panic。
///
/// # Notes
///
/// 请注意,Rust 中的 panics 并不总是通过展开来实现,但是可以通过中止进程来实现。
/// 如果以这种方式实现 panics 时调用了此函数,则此函数将终止进程,而不触发 unwind。
///
///
/// # Examples
///
/// ```should_panic
/// use std::panic;
///
/// let result = panic::catch_unwind(|| {
///     panic!("oh no!");
/// });
///
/// if let Err(err) = result {
///     panic::resume_unwind(err);
/// }
/// ```
///
///
#[stable(feature = "resume_unwind", since = "1.9.0")]
pub fn resume_unwind(payload: Box<dyn Any + Send>) -> ! {
    panicking::rust_panic_without_hook(payload)
}

/// 使所有未来的 panic 直接中止,而不运行 panic 钩子或展开。
///
/// 没有办法撤销这个; 效果持续到进程退出或执行 (或等效)。
///
/// # fork 后使用
///
/// 这个函数在 `libc::fork` 之后调用特别有用。在 `fork` 之后,在多线程程序中 (在许多平台上) 调用分配器是不安全的。
/// `fork` 之后的 unwind 到 unwind 通常也是非常不可取的,因为这会导致 unwind 传播到只希望在父级中运行的代码。
///
///
/// `panic::always_abort()` 有助于避免这两种情况。
/// 它直接避免了任何进一步的展开,如果存在 panic,则无需分配即可终止终止,前提是 panic 的参数可以在不分配的情况下进行格式化。
///
/// Examples
///
/// ```no_run
/// #![feature(panic_always_abort)]
/// use std::panic;
///
/// panic::always_abort();
///
/// let _ = panic::catch_unwind(|| {
///     panic!("inside the catch");
/// });
///
/// // 由于 panic,我们已经中止了。
/// unreachable!();
/// ```
///
///
///
#[unstable(feature = "panic_always_abort", issue = "84438")]
pub fn always_abort() {
    crate::panicking::panic_count::set_always_abort();
}

#[cfg(test)]
mod tests;