aboutsummaryrefslogtreecommitdiff
path: root/crates/stdx
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
parent2664aee8e5976f590e2fcb700982488ae2358780 (diff)
Make always-assert crate reusable
Diffstat (limited to 'crates/stdx')
-rw-r--r--crates/stdx/Cargo.toml1
-rw-r--r--crates/stdx/src/lib.rs2
-rw-r--r--crates/stdx/src/macros.rs51
3 files changed, 2 insertions, 52 deletions
diff --git a/crates/stdx/Cargo.toml b/crates/stdx/Cargo.toml
index c47e8d0a8..5866c0a28 100644
--- a/crates/stdx/Cargo.toml
+++ b/crates/stdx/Cargo.toml
@@ -11,6 +11,7 @@ doctest = false
11 11
12[dependencies] 12[dependencies]
13backtrace = { version = "0.3.44", optional = true } 13backtrace = { version = "0.3.44", optional = true }
14always-assert = { version = "0.1.1", features = ["log"] }
14# Think twice before adding anything here 15# Think twice before adding anything here
15 16
16[features] 17[features]
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};
4mod macros; 4mod macros;
5pub mod panic_context; 5pub mod panic_context;
6 6
7pub use crate::macros::{on_assert_failure, set_assert_hook}; 7pub use always_assert::{always, never};
8 8
9#[inline(always)] 9#[inline(always)]
10pub fn is_ci() -> bool { 10pub 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
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}