diff options
Diffstat (limited to 'crates/ra_db')
-rw-r--r-- | crates/ra_db/src/cancellation.rs | 6 | ||||
-rw-r--r-- | crates/ra_db/src/lib.rs | 22 | ||||
-rw-r--r-- | crates/ra_db/src/loc2id.rs | 11 |
3 files changed, 32 insertions, 7 deletions
diff --git a/crates/ra_db/src/cancellation.rs b/crates/ra_db/src/cancellation.rs index 8d38eebfb..32a268553 100644 --- a/crates/ra_db/src/cancellation.rs +++ b/crates/ra_db/src/cancellation.rs | |||
@@ -27,6 +27,12 @@ impl Canceled { | |||
27 | pub(crate) fn new() -> Canceled { | 27 | pub(crate) fn new() -> Canceled { |
28 | Canceled { _private: () } | 28 | Canceled { _private: () } |
29 | } | 29 | } |
30 | |||
31 | pub fn throw() -> ! { | ||
32 | // We use resume and not panic here to avoid running the panic | ||
33 | // hook (that is, to avoid collecting and printing backtrace). | ||
34 | std::panic::resume_unwind(Box::new(Canceled::new())) | ||
35 | } | ||
30 | } | 36 | } |
31 | 37 | ||
32 | impl std::fmt::Display for Canceled { | 38 | impl std::fmt::Display for Canceled { |
diff --git a/crates/ra_db/src/lib.rs b/crates/ra_db/src/lib.rs index fb8ea2496..20e712afe 100644 --- a/crates/ra_db/src/lib.rs +++ b/crates/ra_db/src/lib.rs | |||
@@ -5,6 +5,8 @@ mod input; | |||
5 | mod loc2id; | 5 | mod loc2id; |
6 | pub mod mock; | 6 | pub mod mock; |
7 | 7 | ||
8 | use std::panic; | ||
9 | |||
8 | use ra_syntax::{TextUnit, TextRange, SourceFile, TreePtr}; | 10 | use ra_syntax::{TextUnit, TextRange, SourceFile, TreePtr}; |
9 | 11 | ||
10 | pub use crate::{ | 12 | pub use crate::{ |
@@ -18,13 +20,21 @@ pub use crate::{ | |||
18 | loc2id::LocationIntener, | 20 | loc2id::LocationIntener, |
19 | }; | 21 | }; |
20 | 22 | ||
21 | pub trait BaseDatabase: salsa::Database { | 23 | pub trait BaseDatabase: salsa::Database + panic::RefUnwindSafe { |
22 | fn check_canceled(&self) -> Cancelable<()> { | 24 | fn check_canceled(&self) -> Cancelable<()> { |
23 | if self.salsa_runtime().is_current_revision_canceled() { | 25 | self.salsa_runtime() |
24 | Err(Canceled::new()) | 26 | .if_current_revision_is_canceled(Canceled::throw); |
25 | } else { | 27 | Ok(()) |
26 | Ok(()) | 28 | } |
27 | } | 29 | |
30 | fn catch_canceled<F: FnOnce(&Self) -> T + panic::UnwindSafe, T>( | ||
31 | &self, | ||
32 | f: F, | ||
33 | ) -> Result<T, Canceled> { | ||
34 | panic::catch_unwind(|| f(self)).map_err(|err| match err.downcast::<Canceled>() { | ||
35 | Ok(canceled) => *canceled, | ||
36 | Err(payload) => panic::resume_unwind(payload), | ||
37 | }) | ||
28 | } | 38 | } |
29 | } | 39 | } |
30 | 40 | ||
diff --git a/crates/ra_db/src/loc2id.rs b/crates/ra_db/src/loc2id.rs index 254c52629..359cd893d 100644 --- a/crates/ra_db/src/loc2id.rs +++ b/crates/ra_db/src/loc2id.rs | |||
@@ -1,4 +1,4 @@ | |||
1 | use std::hash::Hash; | 1 | use std::{panic, hash::Hash}; |
2 | 2 | ||
3 | use parking_lot::Mutex; | 3 | use parking_lot::Mutex; |
4 | use rustc_hash::FxHashMap; | 4 | use rustc_hash::FxHashMap; |
@@ -70,6 +70,15 @@ where | |||
70 | map: Mutex<Loc2IdMap<LOC, ID>>, | 70 | map: Mutex<Loc2IdMap<LOC, ID>>, |
71 | } | 71 | } |
72 | 72 | ||
73 | impl<LOC, ID> panic::RefUnwindSafe for LocationIntener<LOC, ID> | ||
74 | where | ||
75 | ID: ArenaId + Clone, | ||
76 | LOC: Clone + Eq + Hash, | ||
77 | ID: panic::RefUnwindSafe, | ||
78 | LOC: panic::RefUnwindSafe, | ||
79 | { | ||
80 | } | ||
81 | |||
73 | impl<LOC, ID> Default for LocationIntener<LOC, ID> | 82 | impl<LOC, ID> Default for LocationIntener<LOC, ID> |
74 | where | 83 | where |
75 | ID: ArenaId + Clone, | 84 | ID: ArenaId + Clone, |