diff options
Diffstat (limited to 'crates/ra_db/src/lib.rs')
-rw-r--r-- | crates/ra_db/src/lib.rs | 27 |
1 files changed, 16 insertions, 11 deletions
diff --git a/crates/ra_db/src/lib.rs b/crates/ra_db/src/lib.rs index ca775030d..926cf0bd5 100644 --- a/crates/ra_db/src/lib.rs +++ b/crates/ra_db/src/lib.rs | |||
@@ -19,7 +19,7 @@ pub use crate::{ | |||
19 | loc2id::LocationIntener, | 19 | loc2id::LocationIntener, |
20 | }; | 20 | }; |
21 | 21 | ||
22 | pub trait CheckCanceled: salsa::Database + panic::RefUnwindSafe { | 22 | pub trait CheckCanceled: panic::RefUnwindSafe { |
23 | /// Aborts current query if there are pending changes. | 23 | /// Aborts current query if there are pending changes. |
24 | /// | 24 | /// |
25 | /// rust-analyzer needs to be able to answer semantic questions about the | 25 | /// rust-analyzer needs to be able to answer semantic questions about the |
@@ -33,16 +33,13 @@ pub trait CheckCanceled: salsa::Database + panic::RefUnwindSafe { | |||
33 | /// | 33 | /// |
34 | /// We implement cancellation by panicking with a special value and catching | 34 | /// We implement cancellation by panicking with a special value and catching |
35 | /// it on the API boundary. Salsa explicitly supports this use-case. | 35 | /// it on the API boundary. Salsa explicitly supports this use-case. |
36 | fn check_canceled(&self) { | 36 | fn check_canceled(&self); |
37 | if self.salsa_runtime().is_current_revision_canceled() { | ||
38 | Canceled::throw() | ||
39 | } | ||
40 | } | ||
41 | 37 | ||
42 | fn catch_canceled<F: FnOnce(&Self) -> T + panic::UnwindSafe, T>( | 38 | fn catch_canceled<F, T>(&self, f: F) -> Result<T, Canceled> |
43 | &self, | 39 | where |
44 | f: F, | 40 | Self: Sized, |
45 | ) -> Result<T, Canceled> { | 41 | F: FnOnce(&Self) -> T + panic::UnwindSafe, |
42 | { | ||
46 | panic::catch_unwind(|| f(self)).map_err(|err| match err.downcast::<Canceled>() { | 43 | panic::catch_unwind(|| f(self)).map_err(|err| match err.downcast::<Canceled>() { |
47 | Ok(canceled) => *canceled, | 44 | Ok(canceled) => *canceled, |
48 | Err(payload) => panic::resume_unwind(payload), | 45 | Err(payload) => panic::resume_unwind(payload), |
@@ -50,6 +47,14 @@ pub trait CheckCanceled: salsa::Database + panic::RefUnwindSafe { | |||
50 | } | 47 | } |
51 | } | 48 | } |
52 | 49 | ||
50 | impl<T: salsa::Database + panic::RefUnwindSafe> CheckCanceled for T { | ||
51 | fn check_canceled(&self) { | ||
52 | if self.salsa_runtime().is_current_revision_canceled() { | ||
53 | Canceled::throw() | ||
54 | } | ||
55 | } | ||
56 | } | ||
57 | |||
53 | #[derive(Clone, Copy, Debug)] | 58 | #[derive(Clone, Copy, Debug)] |
54 | pub struct FilePosition { | 59 | pub struct FilePosition { |
55 | pub file_id: FileId, | 60 | pub file_id: FileId, |
@@ -65,7 +70,7 @@ pub struct FileRange { | |||
65 | /// Database which stores all significant input facts: source code and project | 70 | /// Database which stores all significant input facts: source code and project |
66 | /// model. Everything else in rust-analyzer is derived from these queries. | 71 | /// model. Everything else in rust-analyzer is derived from these queries. |
67 | #[salsa::query_group(SourceDatabaseStorage)] | 72 | #[salsa::query_group(SourceDatabaseStorage)] |
68 | pub trait SourceDatabase: salsa::Database + CheckCanceled { | 73 | pub trait SourceDatabase: CheckCanceled { |
69 | /// Text of the file. | 74 | /// Text of the file. |
70 | #[salsa::input] | 75 | #[salsa::input] |
71 | fn file_text(&self, file_id: FileId) -> Arc<String>; | 76 | fn file_text(&self, file_id: FileId) -> Arc<String>; |