diff options
Diffstat (limited to 'crates')
-rw-r--r-- | crates/ra_db/src/lib.rs | 16 | ||||
-rw-r--r-- | crates/ra_hir/src/module_tree.rs | 4 | ||||
-rw-r--r-- | crates/ra_hir/src/nameres.rs | 2 | ||||
-rw-r--r-- | crates/ra_hir/src/ty.rs | 2 | ||||
-rw-r--r-- | crates/ra_ide_api/src/symbol_index.rs | 2 |
5 files changed, 19 insertions, 7 deletions
diff --git a/crates/ra_db/src/lib.rs b/crates/ra_db/src/lib.rs index 0e7f32e66..8473fc050 100644 --- a/crates/ra_db/src/lib.rs +++ b/crates/ra_db/src/lib.rs | |||
@@ -21,11 +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 | /// | ||
26 | /// rust-analyzer needs to be able to answer semantic questions about the | ||
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) { | ||
25 | if self.salsa_runtime().is_current_revision_canceled() { | 38 | if self.salsa_runtime().is_current_revision_canceled() { |
26 | Canceled::throw() | 39 | Canceled::throw() |
27 | } | 40 | } |
28 | Ok(()) | ||
29 | } | 41 | } |
30 | 42 | ||
31 | fn catch_canceled<F: FnOnce(&Self) -> T + panic::UnwindSafe, T>( | 43 | fn catch_canceled<F: FnOnce(&Self) -> T + panic::UnwindSafe, T>( |
diff --git a/crates/ra_hir/src/module_tree.rs b/crates/ra_hir/src/module_tree.rs index 67823e970..fd5a92c5b 100644 --- a/crates/ra_hir/src/module_tree.rs +++ b/crates/ra_hir/src/module_tree.rs | |||
@@ -42,7 +42,7 @@ impl Submodule { | |||
42 | db: &impl HirDatabase, | 42 | db: &impl HirDatabase, |
43 | source: SourceItemId, | 43 | source: SourceItemId, |
44 | ) -> Cancelable<Arc<Vec<Submodule>>> { | 44 | ) -> Cancelable<Arc<Vec<Submodule>>> { |
45 | db.check_canceled()?; | 45 | db.check_canceled(); |
46 | let file_id = source.file_id; | 46 | let file_id = source.file_id; |
47 | let file_items = db.file_items(file_id); | 47 | let file_items = db.file_items(file_id); |
48 | let module_source = ModuleSource::from_source_item_id(db, source); | 48 | let module_source = ModuleSource::from_source_item_id(db, source); |
@@ -117,7 +117,7 @@ impl ModuleTree { | |||
117 | db: &impl HirDatabase, | 117 | db: &impl HirDatabase, |
118 | source_root: SourceRootId, | 118 | source_root: SourceRootId, |
119 | ) -> Cancelable<Arc<ModuleTree>> { | 119 | ) -> Cancelable<Arc<ModuleTree>> { |
120 | db.check_canceled()?; | 120 | db.check_canceled(); |
121 | let res = create_module_tree(db, source_root); | 121 | let res = create_module_tree(db, source_root); |
122 | Ok(Arc::new(res?)) | 122 | Ok(Arc::new(res?)) |
123 | } | 123 | } |
diff --git a/crates/ra_hir/src/nameres.rs b/crates/ra_hir/src/nameres.rs index 6bf949654..edb3b1e64 100644 --- a/crates/ra_hir/src/nameres.rs +++ b/crates/ra_hir/src/nameres.rs | |||
@@ -327,7 +327,7 @@ where | |||
327 | loop { | 327 | loop { |
328 | let processed_imports_count = self.processed_imports.len(); | 328 | let processed_imports_count = self.processed_imports.len(); |
329 | for &module_id in self.input.keys() { | 329 | for &module_id in self.input.keys() { |
330 | self.db.check_canceled()?; | 330 | self.db.check_canceled(); |
331 | self.resolve_imports(module_id)?; | 331 | self.resolve_imports(module_id)?; |
332 | } | 332 | } |
333 | if processed_imports_count == self.processed_imports.len() { | 333 | if processed_imports_count == self.processed_imports.len() { |
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs index 5579db8fb..03787bd89 100644 --- a/crates/ra_hir/src/ty.rs +++ b/crates/ra_hir/src/ty.rs | |||
@@ -1203,7 +1203,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1203 | } | 1203 | } |
1204 | 1204 | ||
1205 | pub fn infer(db: &impl HirDatabase, def_id: DefId) -> Cancelable<Arc<InferenceResult>> { | 1205 | pub fn infer(db: &impl HirDatabase, def_id: DefId) -> Cancelable<Arc<InferenceResult>> { |
1206 | db.check_canceled()?; | 1206 | db.check_canceled(); |
1207 | let function = Function::new(def_id); // TODO: consts also need inference | 1207 | let function = Function::new(def_id); // TODO: consts also need inference |
1208 | let body = function.body(db)?; | 1208 | let body = function.body(db)?; |
1209 | let scopes = db.fn_scopes(def_id)?; | 1209 | let scopes = db.fn_scopes(def_id)?; |
diff --git a/crates/ra_ide_api/src/symbol_index.rs b/crates/ra_ide_api/src/symbol_index.rs index fdda57022..b7a3a3550 100644 --- a/crates/ra_ide_api/src/symbol_index.rs +++ b/crates/ra_ide_api/src/symbol_index.rs | |||
@@ -54,7 +54,7 @@ salsa::query_group! { | |||
54 | } | 54 | } |
55 | 55 | ||
56 | fn file_symbols(db: &impl SymbolsDatabase, file_id: FileId) -> Cancelable<Arc<SymbolIndex>> { | 56 | fn file_symbols(db: &impl SymbolsDatabase, file_id: FileId) -> Cancelable<Arc<SymbolIndex>> { |
57 | db.check_canceled()?; | 57 | db.check_canceled(); |
58 | let source_file = db.source_file(file_id); | 58 | let source_file = db.source_file(file_id); |
59 | let mut symbols = source_file | 59 | let mut symbols = source_file |
60 | .syntax() | 60 | .syntax() |