aboutsummaryrefslogtreecommitdiff
path: root/crates/stdx/src/macros.rs
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2021-01-26 19:11:12 +0000
committerAleksey Kladov <[email protected]>2021-01-26 19:13:42 +0000
commitd35bda6429b0a3a758ddcd899e954043584f1071 (patch)
tree3371f60836fdab03f218793582d428ef7751fe55 /crates/stdx/src/macros.rs
parent2664aee8e5976f590e2fcb700982488ae2358780 (diff)
Make always-assert crate reusable
Diffstat (limited to 'crates/stdx/src/macros.rs')
-rw-r--r--crates/stdx/src/macros.rs51
1 files changed, 0 insertions, 51 deletions
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
3use std::{
4 fmt, mem, panic,
5 sync::atomic::{AtomicUsize, Ordering::SeqCst},
6};
7#[macro_export] 3#[macro_export]
8macro_rules! eprintln { 4macro_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]
68macro_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
81type AssertHook = fn(&panic::Location<'_>, fmt::Arguments<'_>);
82static HOOK: AtomicUsize = AtomicUsize::new(0);
83
84pub fn set_assert_hook(hook: AssertHook) {
85 HOOK.store(hook as usize, SeqCst);
86}
87
88#[cold]
89#[track_caller]
90pub 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}