diff options
Diffstat (limited to 'crates/ra_db/src')
-rw-r--r-- | crates/ra_db/src/cancellation.rs | 2 | ||||
-rw-r--r-- | crates/ra_db/src/lib.rs | 23 |
2 files changed, 18 insertions, 7 deletions
diff --git a/crates/ra_db/src/cancellation.rs b/crates/ra_db/src/cancellation.rs index 32a268553..439080075 100644 --- a/crates/ra_db/src/cancellation.rs +++ b/crates/ra_db/src/cancellation.rs | |||
@@ -21,8 +21,6 @@ pub struct Canceled { | |||
21 | _private: (), | 21 | _private: (), |
22 | } | 22 | } |
23 | 23 | ||
24 | pub type Cancelable<T> = Result<T, Canceled>; | ||
25 | |||
26 | impl Canceled { | 24 | impl Canceled { |
27 | pub(crate) fn new() -> Canceled { | 25 | pub(crate) fn new() -> Canceled { |
28 | Canceled { _private: () } | 26 | Canceled { _private: () } |
diff --git a/crates/ra_db/src/lib.rs b/crates/ra_db/src/lib.rs index 0c4dfc8c6..89113e7a6 100644 --- a/crates/ra_db/src/lib.rs +++ b/crates/ra_db/src/lib.rs | |||
@@ -10,7 +10,7 @@ use std::panic; | |||
10 | use ra_syntax::{TextUnit, TextRange, SourceFile, TreeArc}; | 10 | use ra_syntax::{TextUnit, TextRange, SourceFile, TreeArc}; |
11 | 11 | ||
12 | pub use crate::{ | 12 | pub use crate::{ |
13 | cancellation::{Canceled, Cancelable}, | 13 | cancellation::Canceled, |
14 | syntax_ptr::LocalSyntaxPtr, | 14 | syntax_ptr::LocalSyntaxPtr, |
15 | input::{ | 15 | input::{ |
16 | FilesDatabase, FileId, CrateId, SourceRoot, SourceRootId, CrateGraph, Dependency, | 16 | FilesDatabase, FileId, CrateId, SourceRoot, SourceRootId, CrateGraph, Dependency, |
@@ -21,10 +21,23 @@ pub use crate::{ | |||
21 | }; | 21 | }; |
22 | 22 | ||
23 | pub trait BaseDatabase: salsa::Database + panic::RefUnwindSafe { | 23 | pub trait BaseDatabase: salsa::Database + panic::RefUnwindSafe { |
24 | fn check_canceled(&self) -> Cancelable<()> { | 24 | /// Aborts current query if there are pending changes. |
25 | self.salsa_runtime() | 25 | /// |
26 | .if_current_revision_is_canceled(Canceled::throw); | 26 | /// rust-analyzer needs to be able to answer semantic questions about the |
27 | Ok(()) | 27 | /// code while the code is being modified. A common problem is that a |
28 | /// long-running query is being calculated when a new change arrives. | ||
29 | /// | ||
30 | /// We can't just apply the change immediately: this will cause the pending | ||
31 | /// query to see inconsistent state (it will observe an absence of | ||
32 | /// repeatable read). So what we do is we **cancel** all pending queries | ||
33 | /// before applying the change. | ||
34 | /// | ||
35 | /// We implement cancellation by panicking with a special value and catching | ||
36 | /// it on the API boundary. Salsa explicitly supports this use-case. | ||
37 | fn check_canceled(&self) { | ||
38 | if self.salsa_runtime().is_current_revision_canceled() { | ||
39 | Canceled::throw() | ||
40 | } | ||
28 | } | 41 | } |
29 | 42 | ||
30 | fn catch_canceled<F: FnOnce(&Self) -> T + panic::UnwindSafe, T>( | 43 | fn catch_canceled<F: FnOnce(&Self) -> T + panic::UnwindSafe, T>( |