aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_db/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_db/src')
-rw-r--r--crates/ra_db/src/cancellation.rs2
-rw-r--r--crates/ra_db/src/lib.rs23
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
24pub type Cancelable<T> = Result<T, Canceled>;
25
26impl Canceled { 24impl 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;
10use ra_syntax::{TextUnit, TextRange, SourceFile, TreeArc}; 10use ra_syntax::{TextUnit, TextRange, SourceFile, TreeArc};
11 11
12pub use crate::{ 12pub 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
23pub trait BaseDatabase: salsa::Database + panic::RefUnwindSafe { 23pub 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>(