diff options
Diffstat (limited to 'crates/stdx/src')
-rw-r--r-- | crates/stdx/src/lib.rs | 2 | ||||
-rw-r--r-- | crates/stdx/src/macros.rs | 51 |
2 files changed, 1 insertions, 52 deletions
diff --git a/crates/stdx/src/lib.rs b/crates/stdx/src/lib.rs index d42817078..d26be4853 100644 --- a/crates/stdx/src/lib.rs +++ b/crates/stdx/src/lib.rs | |||
@@ -4,7 +4,7 @@ use std::{cmp::Ordering, ops, process, time::Instant}; | |||
4 | mod macros; | 4 | mod macros; |
5 | pub mod panic_context; | 5 | pub mod panic_context; |
6 | 6 | ||
7 | pub use crate::macros::{on_assert_failure, set_assert_hook}; | 7 | pub use always_assert::{always, never}; |
8 | 8 | ||
9 | #[inline(always)] | 9 | #[inline(always)] |
10 | pub fn is_ci() -> bool { | 10 | pub fn is_ci() -> bool { |
diff --git a/crates/stdx/src/macros.rs b/crates/stdx/src/macros.rs index 4f5c6100d..d91fc690c 100644 --- a/crates/stdx/src/macros.rs +++ b/crates/stdx/src/macros.rs | |||
@@ -1,9 +1,5 @@ | |||
1 | //! Convenience macros. | 1 | //! Convenience macros. |
2 | 2 | ||
3 | use std::{ | ||
4 | fmt, mem, panic, | ||
5 | sync::atomic::{AtomicUsize, Ordering::SeqCst}, | ||
6 | }; | ||
7 | #[macro_export] | 3 | #[macro_export] |
8 | macro_rules! eprintln { | 4 | macro_rules! eprintln { |
9 | ($($tt:tt)*) => {{ | 5 | ($($tt:tt)*) => {{ |
@@ -49,50 +45,3 @@ macro_rules! impl_from { | |||
49 | )* | 45 | )* |
50 | } | 46 | } |
51 | } | 47 | } |
52 | |||
53 | /// A version of `assert!` macro which allows to handle an assertion failure. | ||
54 | /// | ||
55 | /// In release mode, it returns the condition and logs an error. | ||
56 | /// | ||
57 | /// ``` | ||
58 | /// if assert_never!(impossible) { | ||
59 | /// // Heh, this shouldn't have happened, but lets try to soldier on... | ||
60 | /// return None; | ||
61 | /// } | ||
62 | /// ``` | ||
63 | /// | ||
64 | /// Rust analyzer is a long-running process, and crashing really isn't an option. | ||
65 | /// | ||
66 | /// Shamelessly stolen from: https://www.sqlite.org/assert.html | ||
67 | #[macro_export] | ||
68 | macro_rules! assert_never { | ||
69 | ($cond:expr) => { $crate::assert_never!($cond, "") }; | ||
70 | ($cond:expr, $($fmt:tt)*) => {{ | ||
71 | let value = $cond; | ||
72 | if value { | ||
73 | $crate::on_assert_failure( | ||
74 | format_args!($($fmt)*) | ||
75 | ); | ||
76 | } | ||
77 | value | ||
78 | }}; | ||
79 | } | ||
80 | |||
81 | type AssertHook = fn(&panic::Location<'_>, fmt::Arguments<'_>); | ||
82 | static HOOK: AtomicUsize = AtomicUsize::new(0); | ||
83 | |||
84 | pub fn set_assert_hook(hook: AssertHook) { | ||
85 | HOOK.store(hook as usize, SeqCst); | ||
86 | } | ||
87 | |||
88 | #[cold] | ||
89 | #[track_caller] | ||
90 | pub fn on_assert_failure(args: fmt::Arguments) { | ||
91 | let hook: usize = HOOK.load(SeqCst); | ||
92 | if hook == 0 { | ||
93 | panic!("\n assertion failed: {}\n", args); | ||
94 | } | ||
95 | |||
96 | let hook: AssertHook = unsafe { mem::transmute::<usize, AssertHook>(hook) }; | ||
97 | hook(panic::Location::caller(), args) | ||
98 | } | ||