-
-/// A version of `assert!` macro which allows to handle an assertion failure.
-///
-/// In release mode, it returns the condition and logs an error.
-///
-/// ```
-/// if assert_never!(impossible) {
-/// // Heh, this shouldn't have happened, but lets try to soldier on...
-/// return None;
-/// }
-/// ```
-///
-/// Rust analyzer is a long-running process, and crashing really isn't an option.
-///
-/// Shamelessly stolen from: https://www.sqlite.org/assert.html
-#[macro_export]
-macro_rules! assert_never {
- ($cond:expr) => { $crate::assert_never!($cond, "") };
- ($cond:expr, $($fmt:tt)*) => {{
- let value = $cond;
- if value {
- $crate::on_assert_failure(
- format_args!($($fmt)*)
- );
- }
- value
- }};
-}
-
-type AssertHook = fn(&panic::Location<'_>, fmt::Arguments<'_>);
-static HOOK: AtomicUsize = AtomicUsize::new(0);
-
-pub fn set_assert_hook(hook: AssertHook) {
- HOOK.store(hook as usize, SeqCst);
-}
-
-#[cold]
-#[track_caller]
-pub fn on_assert_failure(args: fmt::Arguments) {
- let hook: usize = HOOK.load(SeqCst);
- if hook == 0 {
- panic!("\n assertion failed: {}\n", args);
- }
-
- let hook: AssertHook = unsafe { mem::transmute::<usize, AssertHook>(hook) };
- hook(panic::Location::caller(), args)
-}