diff options
author | Aleksey Kladov <[email protected]> | 2021-01-26 19:11:12 +0000 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2021-01-26 19:13:42 +0000 |
commit | d35bda6429b0a3a758ddcd899e954043584f1071 (patch) | |
tree | 3371f60836fdab03f218793582d428ef7751fe55 /crates | |
parent | 2664aee8e5976f590e2fcb700982488ae2358780 (diff) |
Make always-assert crate reusable
Diffstat (limited to 'crates')
-rw-r--r-- | crates/completion/src/item.rs | 4 | ||||
-rw-r--r-- | crates/ide/src/references/rename.rs | 6 | ||||
-rw-r--r-- | crates/ide_db/src/source_change.rs | 7 | ||||
-rw-r--r-- | crates/rust-analyzer/Cargo.toml | 2 | ||||
-rw-r--r-- | crates/rust-analyzer/src/bin/main.rs | 9 | ||||
-rw-r--r-- | crates/stdx/Cargo.toml | 1 | ||||
-rw-r--r-- | crates/stdx/src/lib.rs | 2 | ||||
-rw-r--r-- | crates/stdx/src/macros.rs | 51 |
8 files changed, 11 insertions, 71 deletions
diff --git a/crates/completion/src/item.rs b/crates/completion/src/item.rs index eeb952ec3..8ec4ac65e 100644 --- a/crates/completion/src/item.rs +++ b/crates/completion/src/item.rs | |||
@@ -10,7 +10,7 @@ use ide_db::{ | |||
10 | }, | 10 | }, |
11 | SymbolKind, | 11 | SymbolKind, |
12 | }; | 12 | }; |
13 | use stdx::{assert_never, impl_from}; | 13 | use stdx::{impl_from, never}; |
14 | use syntax::{algo, TextRange}; | 14 | use syntax::{algo, TextRange}; |
15 | use text_edit::TextEdit; | 15 | use text_edit::TextEdit; |
16 | 16 | ||
@@ -404,7 +404,7 @@ impl Builder { | |||
404 | pub(crate) fn set_detail(mut self, detail: Option<impl Into<String>>) -> Builder { | 404 | pub(crate) fn set_detail(mut self, detail: Option<impl Into<String>>) -> Builder { |
405 | self.detail = detail.map(Into::into); | 405 | self.detail = detail.map(Into::into); |
406 | if let Some(detail) = &self.detail { | 406 | if let Some(detail) = &self.detail { |
407 | if assert_never!(detail.contains('\n'), "multiline detail:\n{}", detail) { | 407 | if never!(detail.contains('\n'), "multiline detail:\n{}", detail) { |
408 | self.detail = Some(detail.splitn(2, '\n').next().unwrap().to_string()); | 408 | self.detail = Some(detail.splitn(2, '\n').next().unwrap().to_string()); |
409 | } | 409 | } |
410 | } | 410 | } |
diff --git a/crates/ide/src/references/rename.rs b/crates/ide/src/references/rename.rs index c25bcce50..99a558532 100644 --- a/crates/ide/src/references/rename.rs +++ b/crates/ide/src/references/rename.rs | |||
@@ -9,7 +9,7 @@ use ide_db::{ | |||
9 | search::FileReference, | 9 | search::FileReference, |
10 | RootDatabase, | 10 | RootDatabase, |
11 | }; | 11 | }; |
12 | use stdx::assert_never; | 12 | use stdx::never; |
13 | use syntax::{ | 13 | use syntax::{ |
14 | ast::{self, NameOwner}, | 14 | ast::{self, NameOwner}, |
15 | lex_single_syntax_kind, AstNode, SyntaxKind, SyntaxNode, T, | 15 | lex_single_syntax_kind, AstNode, SyntaxKind, SyntaxNode, T, |
@@ -285,7 +285,7 @@ fn rename_mod( | |||
285 | } | 285 | } |
286 | 286 | ||
287 | fn rename_to_self(sema: &Semantics<RootDatabase>, local: hir::Local) -> RenameResult<SourceChange> { | 287 | fn rename_to_self(sema: &Semantics<RootDatabase>, local: hir::Local) -> RenameResult<SourceChange> { |
288 | if assert_never!(local.is_self(sema.db)) { | 288 | if never!(local.is_self(sema.db)) { |
289 | bail!("rename_to_self invoked on self"); | 289 | bail!("rename_to_self invoked on self"); |
290 | } | 290 | } |
291 | 291 | ||
@@ -388,7 +388,7 @@ fn rename_self_to_param( | |||
388 | let (file_id, self_param) = match local.source(sema.db) { | 388 | let (file_id, self_param) = match local.source(sema.db) { |
389 | InFile { file_id, value: Either::Right(self_param) } => (file_id, self_param), | 389 | InFile { file_id, value: Either::Right(self_param) } => (file_id, self_param), |
390 | _ => { | 390 | _ => { |
391 | assert_never!(true, "rename_self_to_param invoked on a non-self local"); | 391 | never!(true, "rename_self_to_param invoked on a non-self local"); |
392 | bail!("rename_self_to_param invoked on a non-self local"); | 392 | bail!("rename_self_to_param invoked on a non-self local"); |
393 | } | 393 | } |
394 | }; | 394 | }; |
diff --git a/crates/ide_db/src/source_change.rs b/crates/ide_db/src/source_change.rs index b1f87731b..f76bac151 100644 --- a/crates/ide_db/src/source_change.rs +++ b/crates/ide_db/src/source_change.rs | |||
@@ -10,7 +10,7 @@ use std::{ | |||
10 | 10 | ||
11 | use base_db::{AnchoredPathBuf, FileId}; | 11 | use base_db::{AnchoredPathBuf, FileId}; |
12 | use rustc_hash::FxHashMap; | 12 | use rustc_hash::FxHashMap; |
13 | use stdx::assert_never; | 13 | use stdx::never; |
14 | use text_edit::TextEdit; | 14 | use text_edit::TextEdit; |
15 | 15 | ||
16 | #[derive(Default, Debug, Clone)] | 16 | #[derive(Default, Debug, Clone)] |
@@ -40,10 +40,7 @@ impl SourceChange { | |||
40 | pub fn insert_source_edit(&mut self, file_id: FileId, edit: TextEdit) { | 40 | pub fn insert_source_edit(&mut self, file_id: FileId, edit: TextEdit) { |
41 | match self.source_file_edits.entry(file_id) { | 41 | match self.source_file_edits.entry(file_id) { |
42 | Entry::Occupied(mut entry) => { | 42 | Entry::Occupied(mut entry) => { |
43 | assert_never!( | 43 | never!(entry.get_mut().union(edit).is_err(), "overlapping edits for same file"); |
44 | entry.get_mut().union(edit).is_err(), | ||
45 | "overlapping edits for same file" | ||
46 | ); | ||
47 | } | 44 | } |
48 | Entry::Vacant(entry) => { | 45 | Entry::Vacant(entry) => { |
49 | entry.insert(edit); | 46 | entry.insert(edit); |
diff --git a/crates/rust-analyzer/Cargo.toml b/crates/rust-analyzer/Cargo.toml index 268c00942..82ea76666 100644 --- a/crates/rust-analyzer/Cargo.toml +++ b/crates/rust-analyzer/Cargo.toml | |||
@@ -37,6 +37,7 @@ lsp-server = "0.5.0" | |||
37 | tracing = "0.1" | 37 | tracing = "0.1" |
38 | tracing-subscriber = { version = "0.2", default-features = false, features = ["env-filter", "registry"] } | 38 | tracing-subscriber = { version = "0.2", default-features = false, features = ["env-filter", "registry"] } |
39 | tracing-tree = { version = "0.1.4" } | 39 | tracing-tree = { version = "0.1.4" } |
40 | always-assert = "0.1" | ||
40 | 41 | ||
41 | stdx = { path = "../stdx", version = "0.0.0" } | 42 | stdx = { path = "../stdx", version = "0.0.0" } |
42 | flycheck = { path = "../flycheck", version = "0.0.0" } | 43 | flycheck = { path = "../flycheck", version = "0.0.0" } |
@@ -72,3 +73,4 @@ tt = { path = "../tt" } | |||
72 | 73 | ||
73 | [features] | 74 | [features] |
74 | jemalloc = ["jemallocator", "profile/jemalloc"] | 75 | jemalloc = ["jemallocator", "profile/jemalloc"] |
76 | force-always-assert = ["always-assert/force"] | ||
diff --git a/crates/rust-analyzer/src/bin/main.rs b/crates/rust-analyzer/src/bin/main.rs index 1d6e5478b..bee2eedbc 100644 --- a/crates/rust-analyzer/src/bin/main.rs +++ b/crates/rust-analyzer/src/bin/main.rs | |||
@@ -75,15 +75,6 @@ fn setup_logging(log_file: Option<PathBuf>) -> Result<()> { | |||
75 | 75 | ||
76 | profile::init(); | 76 | profile::init(); |
77 | 77 | ||
78 | if !cfg!(debug_assertions) { | ||
79 | stdx::set_assert_hook(|loc, args| { | ||
80 | if env::var("RA_PROFILE").is_ok() { | ||
81 | panic!("assertion failed at {}: {}", loc, args) | ||
82 | } | ||
83 | log::error!("assertion failed at {}: {}", loc, args) | ||
84 | }); | ||
85 | } | ||
86 | |||
87 | Ok(()) | 78 | Ok(()) |
88 | } | 79 | } |
89 | 80 | ||
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] |
13 | backtrace = { version = "0.3.44", optional = true } | 13 | backtrace = { version = "0.3.44", optional = true } |
14 | always-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}; | |||
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 | } | ||