diff options
author | Jonas Schievink <[email protected]> | 2021-05-17 18:07:10 +0100 |
---|---|---|
committer | Jonas Schievink <[email protected]> | 2021-05-27 14:05:41 +0100 |
commit | 33debc40654be9e9061c53784f6c762b2fd21eba (patch) | |
tree | def63d3cc42fe48b1dfdf716c2e8e56de5324dab /crates | |
parent | d0a4ba294ccf0c925a5ff1115c19a60c6a24b734 (diff) |
Update salsa
Diffstat (limited to 'crates')
-rw-r--r-- | crates/base_db/src/cancellation.rs | 48 | ||||
-rw-r--r-- | crates/base_db/src/lib.rs | 45 | ||||
-rw-r--r-- | crates/hir/src/semantics.rs | 2 | ||||
-rw-r--r-- | crates/hir_def/src/nameres/collector.rs | 4 | ||||
-rw-r--r-- | crates/hir_ty/src/infer/expr.rs | 2 | ||||
-rw-r--r-- | crates/hir_ty/src/traits.rs | 2 | ||||
-rw-r--r-- | crates/ide/src/lib.rs | 128 | ||||
-rw-r--r-- | crates/ide_db/src/lib.rs | 20 | ||||
-rw-r--r-- | crates/ide_db/src/symbol_index.rs | 2 | ||||
-rw-r--r-- | crates/rust-analyzer/src/dispatch.rs | 4 | ||||
-rw-r--r-- | crates/rust-analyzer/src/global_state.rs | 4 | ||||
-rw-r--r-- | crates/rust-analyzer/src/lsp_utils.rs | 6 | ||||
-rw-r--r-- | crates/rust-analyzer/src/main_loop.rs | 4 | ||||
-rw-r--r-- | crates/rust-analyzer/src/to_proto.rs | 6 |
14 files changed, 93 insertions, 184 deletions
diff --git a/crates/base_db/src/cancellation.rs b/crates/base_db/src/cancellation.rs deleted file mode 100644 index 7420a1976..000000000 --- a/crates/base_db/src/cancellation.rs +++ /dev/null | |||
@@ -1,48 +0,0 @@ | |||
1 | //! Utility types to support cancellation. | ||
2 | //! | ||
3 | //! In a typical IDE use-case, requests and modification happen concurrently, as | ||
4 | //! in the following scenario: | ||
5 | //! | ||
6 | //! * user types a character, | ||
7 | //! * a syntax highlighting process is started | ||
8 | //! * user types next character, while syntax highlighting *is still in | ||
9 | //! progress*. | ||
10 | //! | ||
11 | //! In this situation, we want to react to modification as quickly as possible. | ||
12 | //! At the same time, in-progress results are not very interesting, because they | ||
13 | //! are invalidated by the edit anyway. So, we first cancel all in-flight | ||
14 | //! requests, and then apply modification knowing that it won't interfere with | ||
15 | //! any background processing (this bit is handled by salsa, see the | ||
16 | //! `BaseDatabase::check_canceled` method). | ||
17 | |||
18 | /// An "error" signifying that the operation was canceled. | ||
19 | #[derive(Clone, PartialEq, Eq, Hash)] | ||
20 | pub struct Canceled { | ||
21 | _private: (), | ||
22 | } | ||
23 | |||
24 | impl Canceled { | ||
25 | pub(crate) fn new() -> Canceled { | ||
26 | Canceled { _private: () } | ||
27 | } | ||
28 | |||
29 | pub fn throw() -> ! { | ||
30 | // We use resume and not panic here to avoid running the panic | ||
31 | // hook (that is, to avoid collecting and printing backtrace). | ||
32 | std::panic::resume_unwind(Box::new(Canceled::new())) | ||
33 | } | ||
34 | } | ||
35 | |||
36 | impl std::fmt::Display for Canceled { | ||
37 | fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||
38 | fmt.write_str("canceled") | ||
39 | } | ||
40 | } | ||
41 | |||
42 | impl std::fmt::Debug for Canceled { | ||
43 | fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||
44 | write!(fmt, "Canceled") | ||
45 | } | ||
46 | } | ||
47 | |||
48 | impl std::error::Error for Canceled {} | ||
diff --git a/crates/base_db/src/lib.rs b/crates/base_db/src/lib.rs index 980a0ed98..62bf2a4b2 100644 --- a/crates/base_db/src/lib.rs +++ b/crates/base_db/src/lib.rs | |||
@@ -1,5 +1,4 @@ | |||
1 | //! base_db defines basic database traits. The concrete DB is defined by ide. | 1 | //! base_db defines basic database traits. The concrete DB is defined by ide. |
2 | mod cancellation; | ||
3 | mod input; | 2 | mod input; |
4 | mod change; | 3 | mod change; |
5 | pub mod fixture; | 4 | pub mod fixture; |
@@ -10,14 +9,13 @@ use rustc_hash::FxHashSet; | |||
10 | use syntax::{ast, Parse, SourceFile, TextRange, TextSize}; | 9 | use syntax::{ast, Parse, SourceFile, TextRange, TextSize}; |
11 | 10 | ||
12 | pub use crate::{ | 11 | pub use crate::{ |
13 | cancellation::Canceled, | ||
14 | change::Change, | 12 | change::Change, |
15 | input::{ | 13 | input::{ |
16 | CrateData, CrateDisplayName, CrateGraph, CrateId, CrateName, Dependency, Edition, Env, | 14 | CrateData, CrateDisplayName, CrateGraph, CrateId, CrateName, Dependency, Edition, Env, |
17 | ProcMacro, ProcMacroExpander, ProcMacroId, ProcMacroKind, SourceRoot, SourceRootId, | 15 | ProcMacro, ProcMacroExpander, ProcMacroId, ProcMacroKind, SourceRoot, SourceRootId, |
18 | }, | 16 | }, |
19 | }; | 17 | }; |
20 | pub use salsa; | 18 | pub use salsa::{self, Cancelled}; |
21 | pub use vfs::{file_set::FileSet, AnchoredPath, AnchoredPathBuf, FileId, VfsPath}; | 19 | pub use vfs::{file_set::FileSet, AnchoredPath, AnchoredPathBuf, FileId, VfsPath}; |
22 | 20 | ||
23 | #[macro_export] | 21 | #[macro_export] |
@@ -38,45 +36,6 @@ pub trait Upcast<T: ?Sized> { | |||
38 | fn upcast(&self) -> &T; | 36 | fn upcast(&self) -> &T; |
39 | } | 37 | } |
40 | 38 | ||
41 | pub trait CheckCanceled { | ||
42 | /// Aborts current query if there are pending changes. | ||
43 | /// | ||
44 | /// rust-analyzer needs to be able to answer semantic questions about the | ||
45 | /// code while the code is being modified. A common problem is that a | ||
46 | /// long-running query is being calculated when a new change arrives. | ||
47 | /// | ||
48 | /// We can't just apply the change immediately: this will cause the pending | ||
49 | /// query to see inconsistent state (it will observe an absence of | ||
50 | /// repeatable read). So what we do is we **cancel** all pending queries | ||
51 | /// before applying the change. | ||
52 | /// | ||
53 | /// We implement cancellation by panicking with a special value and catching | ||
54 | /// it on the API boundary. Salsa explicitly supports this use-case. | ||
55 | fn check_canceled(&self); | ||
56 | |||
57 | fn catch_canceled<F, T>(&self, f: F) -> Result<T, Canceled> | ||
58 | where | ||
59 | Self: Sized + panic::RefUnwindSafe, | ||
60 | F: FnOnce(&Self) -> T + panic::UnwindSafe, | ||
61 | { | ||
62 | // Uncomment to debug missing cancellations. | ||
63 | // let _span = profile::heartbeat_span(); | ||
64 | panic::catch_unwind(|| f(self)).map_err(|err| match err.downcast::<Canceled>() { | ||
65 | Ok(canceled) => *canceled, | ||
66 | Err(payload) => panic::resume_unwind(payload), | ||
67 | }) | ||
68 | } | ||
69 | } | ||
70 | |||
71 | impl<T: salsa::Database> CheckCanceled for T { | ||
72 | fn check_canceled(&self) { | ||
73 | // profile::heartbeat(); | ||
74 | if self.salsa_runtime().is_current_revision_canceled() { | ||
75 | Canceled::throw() | ||
76 | } | ||
77 | } | ||
78 | } | ||
79 | |||
80 | #[derive(Clone, Copy, Debug)] | 39 | #[derive(Clone, Copy, Debug)] |
81 | pub struct FilePosition { | 40 | pub struct FilePosition { |
82 | pub file_id: FileId, | 41 | pub file_id: FileId, |
@@ -101,7 +60,7 @@ pub trait FileLoader { | |||
101 | /// Database which stores all significant input facts: source code and project | 60 | /// Database which stores all significant input facts: source code and project |
102 | /// model. Everything else in rust-analyzer is derived from these queries. | 61 | /// model. Everything else in rust-analyzer is derived from these queries. |
103 | #[salsa::query_group(SourceDatabaseStorage)] | 62 | #[salsa::query_group(SourceDatabaseStorage)] |
104 | pub trait SourceDatabase: CheckCanceled + FileLoader + std::fmt::Debug { | 63 | pub trait SourceDatabase: FileLoader + std::fmt::Debug { |
105 | // Parses the file into the syntax tree. | 64 | // Parses the file into the syntax tree. |
106 | #[salsa::invoke(parse_query)] | 65 | #[salsa::invoke(parse_query)] |
107 | fn parse(&self, file_id: FileId) -> Parse<ast::SourceFile>; | 66 | fn parse(&self, file_id: FileId) -> Parse<ast::SourceFile>; |
diff --git a/crates/hir/src/semantics.rs b/crates/hir/src/semantics.rs index 8d3c43d08..c7f2c02e4 100644 --- a/crates/hir/src/semantics.rs +++ b/crates/hir/src/semantics.rs | |||
@@ -361,7 +361,7 @@ impl<'db> SemanticsImpl<'db> { | |||
361 | let sa = self.analyze(&parent); | 361 | let sa = self.analyze(&parent); |
362 | 362 | ||
363 | let token = successors(Some(InFile::new(sa.file_id, token)), |token| { | 363 | let token = successors(Some(InFile::new(sa.file_id, token)), |token| { |
364 | self.db.check_canceled(); | 364 | self.db.unwind_if_cancelled(); |
365 | let macro_call = token.value.ancestors().find_map(ast::MacroCall::cast)?; | 365 | let macro_call = token.value.ancestors().find_map(ast::MacroCall::cast)?; |
366 | let tt = macro_call.token_tree()?; | 366 | let tt = macro_call.token_tree()?; |
367 | if !tt.syntax().text_range().contains_range(token.value.text_range()) { | 367 | if !tt.syntax().text_range().contains_range(token.value.text_range()) { |
diff --git a/crates/hir_def/src/nameres/collector.rs b/crates/hir_def/src/nameres/collector.rs index 4296c6304..716dcf1f7 100644 --- a/crates/hir_def/src/nameres/collector.rs +++ b/crates/hir_def/src/nameres/collector.rs | |||
@@ -351,7 +351,7 @@ impl DefCollector<'_> { | |||
351 | let mut i = 0; | 351 | let mut i = 0; |
352 | 'outer: loop { | 352 | 'outer: loop { |
353 | loop { | 353 | loop { |
354 | self.db.check_canceled(); | 354 | self.db.unwind_if_cancelled(); |
355 | loop { | 355 | loop { |
356 | if self.resolve_imports() == ReachedFixedPoint::Yes { | 356 | if self.resolve_imports() == ReachedFixedPoint::Yes { |
357 | break; | 357 | break; |
@@ -831,7 +831,7 @@ impl DefCollector<'_> { | |||
831 | vis: Visibility, | 831 | vis: Visibility, |
832 | import_type: ImportType, | 832 | import_type: ImportType, |
833 | ) { | 833 | ) { |
834 | self.db.check_canceled(); | 834 | self.db.unwind_if_cancelled(); |
835 | self.update_recursive(module_id, resolutions, vis, import_type, 0) | 835 | self.update_recursive(module_id, resolutions, vis, import_type, 0) |
836 | } | 836 | } |
837 | 837 | ||
diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs index 97507305c..41ef45326 100644 --- a/crates/hir_ty/src/infer/expr.rs +++ b/crates/hir_ty/src/infer/expr.rs | |||
@@ -119,7 +119,7 @@ impl<'a> InferenceContext<'a> { | |||
119 | } | 119 | } |
120 | 120 | ||
121 | fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty { | 121 | fn infer_expr_inner(&mut self, tgt_expr: ExprId, expected: &Expectation) -> Ty { |
122 | self.db.check_canceled(); | 122 | self.db.unwind_if_cancelled(); |
123 | 123 | ||
124 | let body = Arc::clone(&self.body); // avoid borrow checker problem | 124 | let body = Arc::clone(&self.body); // avoid borrow checker problem |
125 | let ty = match &body[tgt_expr] { | 125 | let ty = match &body[tgt_expr] { |
diff --git a/crates/hir_ty/src/traits.rs b/crates/hir_ty/src/traits.rs index 294cb531c..f589b314b 100644 --- a/crates/hir_ty/src/traits.rs +++ b/crates/hir_ty/src/traits.rs | |||
@@ -112,7 +112,7 @@ fn solve( | |||
112 | let fuel = std::cell::Cell::new(CHALK_SOLVER_FUEL); | 112 | let fuel = std::cell::Cell::new(CHALK_SOLVER_FUEL); |
113 | 113 | ||
114 | let should_continue = || { | 114 | let should_continue = || { |
115 | context.db.check_canceled(); | 115 | db.unwind_if_cancelled(); |
116 | let remaining = fuel.get(); | 116 | let remaining = fuel.get(); |
117 | fuel.set(remaining - 1); | 117 | fuel.set(remaining - 1); |
118 | if remaining == 0 { | 118 | if remaining == 0 { |
diff --git a/crates/ide/src/lib.rs b/crates/ide/src/lib.rs index ff2a54117..97c9e5d2b 100644 --- a/crates/ide/src/lib.rs +++ b/crates/ide/src/lib.rs | |||
@@ -58,7 +58,7 @@ use cfg::CfgOptions; | |||
58 | 58 | ||
59 | use ide_db::base_db::{ | 59 | use ide_db::base_db::{ |
60 | salsa::{self, ParallelDatabase}, | 60 | salsa::{self, ParallelDatabase}, |
61 | CheckCanceled, Env, FileLoader, FileSet, SourceDatabase, VfsPath, | 61 | Env, FileLoader, FileSet, SourceDatabase, VfsPath, |
62 | }; | 62 | }; |
63 | use ide_db::{ | 63 | use ide_db::{ |
64 | symbol_index::{self, FileSymbol}, | 64 | symbol_index::{self, FileSymbol}, |
@@ -98,7 +98,7 @@ pub use ide_completion::{ | |||
98 | }; | 98 | }; |
99 | pub use ide_db::{ | 99 | pub use ide_db::{ |
100 | base_db::{ | 100 | base_db::{ |
101 | Canceled, Change, CrateGraph, CrateId, Edition, FileId, FilePosition, FileRange, | 101 | Cancelled, Change, CrateGraph, CrateId, Edition, FileId, FilePosition, FileRange, |
102 | SourceRoot, SourceRootId, | 102 | SourceRoot, SourceRootId, |
103 | }, | 103 | }, |
104 | call_info::CallInfo, | 104 | call_info::CallInfo, |
@@ -113,7 +113,7 @@ pub use ide_ssr::SsrError; | |||
113 | pub use syntax::{TextRange, TextSize}; | 113 | pub use syntax::{TextRange, TextSize}; |
114 | pub use text_edit::{Indel, TextEdit}; | 114 | pub use text_edit::{Indel, TextEdit}; |
115 | 115 | ||
116 | pub type Cancelable<T> = Result<T, Canceled>; | 116 | pub type Cancellable<T> = Result<T, Cancelled>; |
117 | 117 | ||
118 | /// Info associated with a text range. | 118 | /// Info associated with a text range. |
119 | #[derive(Debug)] | 119 | #[derive(Debug)] |
@@ -227,11 +227,11 @@ impl Analysis { | |||
227 | } | 227 | } |
228 | 228 | ||
229 | /// Debug info about the current state of the analysis. | 229 | /// Debug info about the current state of the analysis. |
230 | pub fn status(&self, file_id: Option<FileId>) -> Cancelable<String> { | 230 | pub fn status(&self, file_id: Option<FileId>) -> Cancellable<String> { |
231 | self.with_db(|db| status::status(&*db, file_id)) | 231 | self.with_db(|db| status::status(&*db, file_id)) |
232 | } | 232 | } |
233 | 233 | ||
234 | pub fn prime_caches<F>(&self, cb: F) -> Cancelable<()> | 234 | pub fn prime_caches<F>(&self, cb: F) -> Cancellable<()> |
235 | where | 235 | where |
236 | F: Fn(PrimeCachesProgress) + Sync + std::panic::UnwindSafe, | 236 | F: Fn(PrimeCachesProgress) + Sync + std::panic::UnwindSafe, |
237 | { | 237 | { |
@@ -239,35 +239,35 @@ impl Analysis { | |||
239 | } | 239 | } |
240 | 240 | ||
241 | /// Gets the text of the source file. | 241 | /// Gets the text of the source file. |
242 | pub fn file_text(&self, file_id: FileId) -> Cancelable<Arc<String>> { | 242 | pub fn file_text(&self, file_id: FileId) -> Cancellable<Arc<String>> { |
243 | self.with_db(|db| db.file_text(file_id)) | 243 | self.with_db(|db| db.file_text(file_id)) |
244 | } | 244 | } |
245 | 245 | ||
246 | /// Gets the syntax tree of the file. | 246 | /// Gets the syntax tree of the file. |
247 | pub fn parse(&self, file_id: FileId) -> Cancelable<SourceFile> { | 247 | pub fn parse(&self, file_id: FileId) -> Cancellable<SourceFile> { |
248 | self.with_db(|db| db.parse(file_id).tree()) | 248 | self.with_db(|db| db.parse(file_id).tree()) |
249 | } | 249 | } |
250 | 250 | ||
251 | /// Returns true if this file belongs to an immutable library. | 251 | /// Returns true if this file belongs to an immutable library. |
252 | pub fn is_library_file(&self, file_id: FileId) -> Cancelable<bool> { | 252 | pub fn is_library_file(&self, file_id: FileId) -> Cancellable<bool> { |
253 | use ide_db::base_db::SourceDatabaseExt; | 253 | use ide_db::base_db::SourceDatabaseExt; |
254 | self.with_db(|db| db.source_root(db.file_source_root(file_id)).is_library) | 254 | self.with_db(|db| db.source_root(db.file_source_root(file_id)).is_library) |
255 | } | 255 | } |
256 | 256 | ||
257 | /// Gets the file's `LineIndex`: data structure to convert between absolute | 257 | /// Gets the file's `LineIndex`: data structure to convert between absolute |
258 | /// offsets and line/column representation. | 258 | /// offsets and line/column representation. |
259 | pub fn file_line_index(&self, file_id: FileId) -> Cancelable<Arc<LineIndex>> { | 259 | pub fn file_line_index(&self, file_id: FileId) -> Cancellable<Arc<LineIndex>> { |
260 | self.with_db(|db| db.line_index(file_id)) | 260 | self.with_db(|db| db.line_index(file_id)) |
261 | } | 261 | } |
262 | 262 | ||
263 | /// Selects the next syntactic nodes encompassing the range. | 263 | /// Selects the next syntactic nodes encompassing the range. |
264 | pub fn extend_selection(&self, frange: FileRange) -> Cancelable<TextRange> { | 264 | pub fn extend_selection(&self, frange: FileRange) -> Cancellable<TextRange> { |
265 | self.with_db(|db| extend_selection::extend_selection(db, frange)) | 265 | self.with_db(|db| extend_selection::extend_selection(db, frange)) |
266 | } | 266 | } |
267 | 267 | ||
268 | /// Returns position of the matching brace (all types of braces are | 268 | /// Returns position of the matching brace (all types of braces are |
269 | /// supported). | 269 | /// supported). |
270 | pub fn matching_brace(&self, position: FilePosition) -> Cancelable<Option<TextSize>> { | 270 | pub fn matching_brace(&self, position: FilePosition) -> Cancellable<Option<TextSize>> { |
271 | self.with_db(|db| { | 271 | self.with_db(|db| { |
272 | let parse = db.parse(position.file_id); | 272 | let parse = db.parse(position.file_id); |
273 | let file = parse.tree(); | 273 | let file = parse.tree(); |
@@ -281,30 +281,30 @@ impl Analysis { | |||
281 | &self, | 281 | &self, |
282 | file_id: FileId, | 282 | file_id: FileId, |
283 | text_range: Option<TextRange>, | 283 | text_range: Option<TextRange>, |
284 | ) -> Cancelable<String> { | 284 | ) -> Cancellable<String> { |
285 | self.with_db(|db| syntax_tree::syntax_tree(&db, file_id, text_range)) | 285 | self.with_db(|db| syntax_tree::syntax_tree(&db, file_id, text_range)) |
286 | } | 286 | } |
287 | 287 | ||
288 | pub fn view_hir(&self, position: FilePosition) -> Cancelable<String> { | 288 | pub fn view_hir(&self, position: FilePosition) -> Cancellable<String> { |
289 | self.with_db(|db| view_hir::view_hir(&db, position)) | 289 | self.with_db(|db| view_hir::view_hir(&db, position)) |
290 | } | 290 | } |
291 | 291 | ||
292 | pub fn view_item_tree(&self, file_id: FileId) -> Cancelable<String> { | 292 | pub fn view_item_tree(&self, file_id: FileId) -> Cancellable<String> { |
293 | self.with_db(|db| view_item_tree::view_item_tree(&db, file_id)) | 293 | self.with_db(|db| view_item_tree::view_item_tree(&db, file_id)) |
294 | } | 294 | } |
295 | 295 | ||
296 | /// Renders the crate graph to GraphViz "dot" syntax. | 296 | /// Renders the crate graph to GraphViz "dot" syntax. |
297 | pub fn view_crate_graph(&self) -> Cancelable<Result<String, String>> { | 297 | pub fn view_crate_graph(&self) -> Cancellable<Result<String, String>> { |
298 | self.with_db(|db| view_crate_graph::view_crate_graph(&db)) | 298 | self.with_db(|db| view_crate_graph::view_crate_graph(&db)) |
299 | } | 299 | } |
300 | 300 | ||
301 | pub fn expand_macro(&self, position: FilePosition) -> Cancelable<Option<ExpandedMacro>> { | 301 | pub fn expand_macro(&self, position: FilePosition) -> Cancellable<Option<ExpandedMacro>> { |
302 | self.with_db(|db| expand_macro::expand_macro(db, position)) | 302 | self.with_db(|db| expand_macro::expand_macro(db, position)) |
303 | } | 303 | } |
304 | 304 | ||
305 | /// Returns an edit to remove all newlines in the range, cleaning up minor | 305 | /// Returns an edit to remove all newlines in the range, cleaning up minor |
306 | /// stuff like trailing commas. | 306 | /// stuff like trailing commas. |
307 | pub fn join_lines(&self, frange: FileRange) -> Cancelable<TextEdit> { | 307 | pub fn join_lines(&self, frange: FileRange) -> Cancellable<TextEdit> { |
308 | self.with_db(|db| { | 308 | self.with_db(|db| { |
309 | let parse = db.parse(frange.file_id); | 309 | let parse = db.parse(frange.file_id); |
310 | join_lines::join_lines(&parse.tree(), frange.range) | 310 | join_lines::join_lines(&parse.tree(), frange.range) |
@@ -314,7 +314,7 @@ impl Analysis { | |||
314 | /// Returns an edit which should be applied when opening a new line, fixing | 314 | /// Returns an edit which should be applied when opening a new line, fixing |
315 | /// up minor stuff like continuing the comment. | 315 | /// up minor stuff like continuing the comment. |
316 | /// The edit will be a snippet (with `$0`). | 316 | /// The edit will be a snippet (with `$0`). |
317 | pub fn on_enter(&self, position: FilePosition) -> Cancelable<Option<TextEdit>> { | 317 | pub fn on_enter(&self, position: FilePosition) -> Cancellable<Option<TextEdit>> { |
318 | self.with_db(|db| typing::on_enter(&db, position)) | 318 | self.with_db(|db| typing::on_enter(&db, position)) |
319 | } | 319 | } |
320 | 320 | ||
@@ -326,7 +326,7 @@ impl Analysis { | |||
326 | &self, | 326 | &self, |
327 | position: FilePosition, | 327 | position: FilePosition, |
328 | char_typed: char, | 328 | char_typed: char, |
329 | ) -> Cancelable<Option<SourceChange>> { | 329 | ) -> Cancellable<Option<SourceChange>> { |
330 | // Fast path to not even parse the file. | 330 | // Fast path to not even parse the file. |
331 | if !typing::TRIGGER_CHARS.contains(char_typed) { | 331 | if !typing::TRIGGER_CHARS.contains(char_typed) { |
332 | return Ok(None); | 332 | return Ok(None); |
@@ -336,7 +336,7 @@ impl Analysis { | |||
336 | 336 | ||
337 | /// Returns a tree representation of symbols in the file. Useful to draw a | 337 | /// Returns a tree representation of symbols in the file. Useful to draw a |
338 | /// file outline. | 338 | /// file outline. |
339 | pub fn file_structure(&self, file_id: FileId) -> Cancelable<Vec<StructureNode>> { | 339 | pub fn file_structure(&self, file_id: FileId) -> Cancellable<Vec<StructureNode>> { |
340 | self.with_db(|db| file_structure::file_structure(&db.parse(file_id).tree())) | 340 | self.with_db(|db| file_structure::file_structure(&db.parse(file_id).tree())) |
341 | } | 341 | } |
342 | 342 | ||
@@ -345,17 +345,17 @@ impl Analysis { | |||
345 | &self, | 345 | &self, |
346 | file_id: FileId, | 346 | file_id: FileId, |
347 | config: &InlayHintsConfig, | 347 | config: &InlayHintsConfig, |
348 | ) -> Cancelable<Vec<InlayHint>> { | 348 | ) -> Cancellable<Vec<InlayHint>> { |
349 | self.with_db(|db| inlay_hints::inlay_hints(db, file_id, config)) | 349 | self.with_db(|db| inlay_hints::inlay_hints(db, file_id, config)) |
350 | } | 350 | } |
351 | 351 | ||
352 | /// Returns the set of folding ranges. | 352 | /// Returns the set of folding ranges. |
353 | pub fn folding_ranges(&self, file_id: FileId) -> Cancelable<Vec<Fold>> { | 353 | pub fn folding_ranges(&self, file_id: FileId) -> Cancellable<Vec<Fold>> { |
354 | self.with_db(|db| folding_ranges::folding_ranges(&db.parse(file_id).tree())) | 354 | self.with_db(|db| folding_ranges::folding_ranges(&db.parse(file_id).tree())) |
355 | } | 355 | } |
356 | 356 | ||
357 | /// Fuzzy searches for a symbol. | 357 | /// Fuzzy searches for a symbol. |
358 | pub fn symbol_search(&self, query: Query) -> Cancelable<Vec<NavigationTarget>> { | 358 | pub fn symbol_search(&self, query: Query) -> Cancellable<Vec<NavigationTarget>> { |
359 | self.with_db(|db| { | 359 | self.with_db(|db| { |
360 | symbol_index::world_symbols(db, query) | 360 | symbol_index::world_symbols(db, query) |
361 | .into_iter() | 361 | .into_iter() |
@@ -368,7 +368,7 @@ impl Analysis { | |||
368 | pub fn goto_definition( | 368 | pub fn goto_definition( |
369 | &self, | 369 | &self, |
370 | position: FilePosition, | 370 | position: FilePosition, |
371 | ) -> Cancelable<Option<RangeInfo<Vec<NavigationTarget>>>> { | 371 | ) -> Cancellable<Option<RangeInfo<Vec<NavigationTarget>>>> { |
372 | self.with_db(|db| goto_definition::goto_definition(db, position)) | 372 | self.with_db(|db| goto_definition::goto_definition(db, position)) |
373 | } | 373 | } |
374 | 374 | ||
@@ -376,7 +376,7 @@ impl Analysis { | |||
376 | pub fn goto_implementation( | 376 | pub fn goto_implementation( |
377 | &self, | 377 | &self, |
378 | position: FilePosition, | 378 | position: FilePosition, |
379 | ) -> Cancelable<Option<RangeInfo<Vec<NavigationTarget>>>> { | 379 | ) -> Cancellable<Option<RangeInfo<Vec<NavigationTarget>>>> { |
380 | self.with_db(|db| goto_implementation::goto_implementation(db, position)) | 380 | self.with_db(|db| goto_implementation::goto_implementation(db, position)) |
381 | } | 381 | } |
382 | 382 | ||
@@ -384,7 +384,7 @@ impl Analysis { | |||
384 | pub fn goto_type_definition( | 384 | pub fn goto_type_definition( |
385 | &self, | 385 | &self, |
386 | position: FilePosition, | 386 | position: FilePosition, |
387 | ) -> Cancelable<Option<RangeInfo<Vec<NavigationTarget>>>> { | 387 | ) -> Cancellable<Option<RangeInfo<Vec<NavigationTarget>>>> { |
388 | self.with_db(|db| goto_type_definition::goto_type_definition(db, position)) | 388 | self.with_db(|db| goto_type_definition::goto_type_definition(db, position)) |
389 | } | 389 | } |
390 | 390 | ||
@@ -393,12 +393,12 @@ impl Analysis { | |||
393 | &self, | 393 | &self, |
394 | position: FilePosition, | 394 | position: FilePosition, |
395 | search_scope: Option<SearchScope>, | 395 | search_scope: Option<SearchScope>, |
396 | ) -> Cancelable<Option<ReferenceSearchResult>> { | 396 | ) -> Cancellable<Option<ReferenceSearchResult>> { |
397 | self.with_db(|db| references::find_all_refs(&Semantics::new(db), position, search_scope)) | 397 | self.with_db(|db| references::find_all_refs(&Semantics::new(db), position, search_scope)) |
398 | } | 398 | } |
399 | 399 | ||
400 | /// Finds all methods and free functions for the file. Does not return tests! | 400 | /// Finds all methods and free functions for the file. Does not return tests! |
401 | pub fn find_all_methods(&self, file_id: FileId) -> Cancelable<Vec<FileRange>> { | 401 | pub fn find_all_methods(&self, file_id: FileId) -> Cancellable<Vec<FileRange>> { |
402 | self.with_db(|db| fn_references::find_all_methods(db, file_id)) | 402 | self.with_db(|db| fn_references::find_all_methods(db, file_id)) |
403 | } | 403 | } |
404 | 404 | ||
@@ -408,7 +408,7 @@ impl Analysis { | |||
408 | position: FilePosition, | 408 | position: FilePosition, |
409 | links_in_hover: bool, | 409 | links_in_hover: bool, |
410 | markdown: bool, | 410 | markdown: bool, |
411 | ) -> Cancelable<Option<RangeInfo<HoverResult>>> { | 411 | ) -> Cancellable<Option<RangeInfo<HoverResult>>> { |
412 | self.with_db(|db| hover::hover(db, position, links_in_hover, markdown)) | 412 | self.with_db(|db| hover::hover(db, position, links_in_hover, markdown)) |
413 | } | 413 | } |
414 | 414 | ||
@@ -416,12 +416,12 @@ impl Analysis { | |||
416 | pub fn external_docs( | 416 | pub fn external_docs( |
417 | &self, | 417 | &self, |
418 | position: FilePosition, | 418 | position: FilePosition, |
419 | ) -> Cancelable<Option<doc_links::DocumentationLink>> { | 419 | ) -> Cancellable<Option<doc_links::DocumentationLink>> { |
420 | self.with_db(|db| doc_links::external_docs(db, &position)) | 420 | self.with_db(|db| doc_links::external_docs(db, &position)) |
421 | } | 421 | } |
422 | 422 | ||
423 | /// Computes parameter information for the given call expression. | 423 | /// Computes parameter information for the given call expression. |
424 | pub fn call_info(&self, position: FilePosition) -> Cancelable<Option<CallInfo>> { | 424 | pub fn call_info(&self, position: FilePosition) -> Cancellable<Option<CallInfo>> { |
425 | self.with_db(|db| ide_db::call_info::call_info(db, position)) | 425 | self.with_db(|db| ide_db::call_info::call_info(db, position)) |
426 | } | 426 | } |
427 | 427 | ||
@@ -429,42 +429,42 @@ impl Analysis { | |||
429 | pub fn call_hierarchy( | 429 | pub fn call_hierarchy( |
430 | &self, | 430 | &self, |
431 | position: FilePosition, | 431 | position: FilePosition, |
432 | ) -> Cancelable<Option<RangeInfo<Vec<NavigationTarget>>>> { | 432 | ) -> Cancellable<Option<RangeInfo<Vec<NavigationTarget>>>> { |
433 | self.with_db(|db| call_hierarchy::call_hierarchy(db, position)) | 433 | self.with_db(|db| call_hierarchy::call_hierarchy(db, position)) |
434 | } | 434 | } |
435 | 435 | ||
436 | /// Computes incoming calls for the given file position. | 436 | /// Computes incoming calls for the given file position. |
437 | pub fn incoming_calls(&self, position: FilePosition) -> Cancelable<Option<Vec<CallItem>>> { | 437 | pub fn incoming_calls(&self, position: FilePosition) -> Cancellable<Option<Vec<CallItem>>> { |
438 | self.with_db(|db| call_hierarchy::incoming_calls(db, position)) | 438 | self.with_db(|db| call_hierarchy::incoming_calls(db, position)) |
439 | } | 439 | } |
440 | 440 | ||
441 | /// Computes incoming calls for the given file position. | 441 | /// Computes incoming calls for the given file position. |
442 | pub fn outgoing_calls(&self, position: FilePosition) -> Cancelable<Option<Vec<CallItem>>> { | 442 | pub fn outgoing_calls(&self, position: FilePosition) -> Cancellable<Option<Vec<CallItem>>> { |
443 | self.with_db(|db| call_hierarchy::outgoing_calls(db, position)) | 443 | self.with_db(|db| call_hierarchy::outgoing_calls(db, position)) |
444 | } | 444 | } |
445 | 445 | ||
446 | /// Returns a `mod name;` declaration which created the current module. | 446 | /// Returns a `mod name;` declaration which created the current module. |
447 | pub fn parent_module(&self, position: FilePosition) -> Cancelable<Vec<NavigationTarget>> { | 447 | pub fn parent_module(&self, position: FilePosition) -> Cancellable<Vec<NavigationTarget>> { |
448 | self.with_db(|db| parent_module::parent_module(db, position)) | 448 | self.with_db(|db| parent_module::parent_module(db, position)) |
449 | } | 449 | } |
450 | 450 | ||
451 | /// Returns crates this file belongs too. | 451 | /// Returns crates this file belongs too. |
452 | pub fn crate_for(&self, file_id: FileId) -> Cancelable<Vec<CrateId>> { | 452 | pub fn crate_for(&self, file_id: FileId) -> Cancellable<Vec<CrateId>> { |
453 | self.with_db(|db| parent_module::crate_for(db, file_id)) | 453 | self.with_db(|db| parent_module::crate_for(db, file_id)) |
454 | } | 454 | } |
455 | 455 | ||
456 | /// Returns the edition of the given crate. | 456 | /// Returns the edition of the given crate. |
457 | pub fn crate_edition(&self, crate_id: CrateId) -> Cancelable<Edition> { | 457 | pub fn crate_edition(&self, crate_id: CrateId) -> Cancellable<Edition> { |
458 | self.with_db(|db| db.crate_graph()[crate_id].edition) | 458 | self.with_db(|db| db.crate_graph()[crate_id].edition) |
459 | } | 459 | } |
460 | 460 | ||
461 | /// Returns the root file of the given crate. | 461 | /// Returns the root file of the given crate. |
462 | pub fn crate_root(&self, crate_id: CrateId) -> Cancelable<FileId> { | 462 | pub fn crate_root(&self, crate_id: CrateId) -> Cancellable<FileId> { |
463 | self.with_db(|db| db.crate_graph()[crate_id].root_file_id) | 463 | self.with_db(|db| db.crate_graph()[crate_id].root_file_id) |
464 | } | 464 | } |
465 | 465 | ||
466 | /// Returns the set of possible targets to run for the current file. | 466 | /// Returns the set of possible targets to run for the current file. |
467 | pub fn runnables(&self, file_id: FileId) -> Cancelable<Vec<Runnable>> { | 467 | pub fn runnables(&self, file_id: FileId) -> Cancellable<Vec<Runnable>> { |
468 | self.with_db(|db| runnables::runnables(db, file_id)) | 468 | self.with_db(|db| runnables::runnables(db, file_id)) |
469 | } | 469 | } |
470 | 470 | ||
@@ -473,24 +473,24 @@ impl Analysis { | |||
473 | &self, | 473 | &self, |
474 | position: FilePosition, | 474 | position: FilePosition, |
475 | search_scope: Option<SearchScope>, | 475 | search_scope: Option<SearchScope>, |
476 | ) -> Cancelable<Vec<Runnable>> { | 476 | ) -> Cancellable<Vec<Runnable>> { |
477 | self.with_db(|db| runnables::related_tests(db, position, search_scope)) | 477 | self.with_db(|db| runnables::related_tests(db, position, search_scope)) |
478 | } | 478 | } |
479 | 479 | ||
480 | /// Computes syntax highlighting for the given file | 480 | /// Computes syntax highlighting for the given file |
481 | pub fn highlight(&self, file_id: FileId) -> Cancelable<Vec<HlRange>> { | 481 | pub fn highlight(&self, file_id: FileId) -> Cancellable<Vec<HlRange>> { |
482 | self.with_db(|db| syntax_highlighting::highlight(db, file_id, None, false)) | 482 | self.with_db(|db| syntax_highlighting::highlight(db, file_id, None, false)) |
483 | } | 483 | } |
484 | 484 | ||
485 | /// Computes syntax highlighting for the given file range. | 485 | /// Computes syntax highlighting for the given file range. |
486 | pub fn highlight_range(&self, frange: FileRange) -> Cancelable<Vec<HlRange>> { | 486 | pub fn highlight_range(&self, frange: FileRange) -> Cancellable<Vec<HlRange>> { |
487 | self.with_db(|db| { | 487 | self.with_db(|db| { |
488 | syntax_highlighting::highlight(db, frange.file_id, Some(frange.range), false) | 488 | syntax_highlighting::highlight(db, frange.file_id, Some(frange.range), false) |
489 | }) | 489 | }) |
490 | } | 490 | } |
491 | 491 | ||
492 | /// Computes syntax highlighting for the given file. | 492 | /// Computes syntax highlighting for the given file. |
493 | pub fn highlight_as_html(&self, file_id: FileId, rainbow: bool) -> Cancelable<String> { | 493 | pub fn highlight_as_html(&self, file_id: FileId, rainbow: bool) -> Cancellable<String> { |
494 | self.with_db(|db| syntax_highlighting::highlight_as_html(db, file_id, rainbow)) | 494 | self.with_db(|db| syntax_highlighting::highlight_as_html(db, file_id, rainbow)) |
495 | } | 495 | } |
496 | 496 | ||
@@ -499,7 +499,7 @@ impl Analysis { | |||
499 | &self, | 499 | &self, |
500 | config: &CompletionConfig, | 500 | config: &CompletionConfig, |
501 | position: FilePosition, | 501 | position: FilePosition, |
502 | ) -> Cancelable<Option<Vec<CompletionItem>>> { | 502 | ) -> Cancellable<Option<Vec<CompletionItem>>> { |
503 | self.with_db(|db| ide_completion::completions(db, config, position).map(Into::into)) | 503 | self.with_db(|db| ide_completion::completions(db, config, position).map(Into::into)) |
504 | } | 504 | } |
505 | 505 | ||
@@ -510,7 +510,7 @@ impl Analysis { | |||
510 | position: FilePosition, | 510 | position: FilePosition, |
511 | full_import_path: &str, | 511 | full_import_path: &str, |
512 | imported_name: String, | 512 | imported_name: String, |
513 | ) -> Cancelable<Vec<TextEdit>> { | 513 | ) -> Cancellable<Vec<TextEdit>> { |
514 | Ok(self | 514 | Ok(self |
515 | .with_db(|db| { | 515 | .with_db(|db| { |
516 | ide_completion::resolve_completion_edits( | 516 | ide_completion::resolve_completion_edits( |
@@ -533,7 +533,7 @@ impl Analysis { | |||
533 | config: &AssistConfig, | 533 | config: &AssistConfig, |
534 | resolve: AssistResolveStrategy, | 534 | resolve: AssistResolveStrategy, |
535 | frange: FileRange, | 535 | frange: FileRange, |
536 | ) -> Cancelable<Vec<Assist>> { | 536 | ) -> Cancellable<Vec<Assist>> { |
537 | self.with_db(|db| { | 537 | self.with_db(|db| { |
538 | let ssr_assists = ssr::ssr_assists(db, &resolve, frange); | 538 | let ssr_assists = ssr::ssr_assists(db, &resolve, frange); |
539 | let mut acc = Assist::get(db, config, resolve, frange); | 539 | let mut acc = Assist::get(db, config, resolve, frange); |
@@ -548,7 +548,7 @@ impl Analysis { | |||
548 | config: &DiagnosticsConfig, | 548 | config: &DiagnosticsConfig, |
549 | resolve: AssistResolveStrategy, | 549 | resolve: AssistResolveStrategy, |
550 | file_id: FileId, | 550 | file_id: FileId, |
551 | ) -> Cancelable<Vec<Diagnostic>> { | 551 | ) -> Cancellable<Vec<Diagnostic>> { |
552 | self.with_db(|db| diagnostics::diagnostics(db, config, &resolve, file_id)) | 552 | self.with_db(|db| diagnostics::diagnostics(db, config, &resolve, file_id)) |
553 | } | 553 | } |
554 | 554 | ||
@@ -559,7 +559,7 @@ impl Analysis { | |||
559 | diagnostics_config: &DiagnosticsConfig, | 559 | diagnostics_config: &DiagnosticsConfig, |
560 | resolve: AssistResolveStrategy, | 560 | resolve: AssistResolveStrategy, |
561 | frange: FileRange, | 561 | frange: FileRange, |
562 | ) -> Cancelable<Vec<Assist>> { | 562 | ) -> Cancellable<Vec<Assist>> { |
563 | let include_fixes = match &assist_config.allowed { | 563 | let include_fixes = match &assist_config.allowed { |
564 | Some(it) => it.iter().any(|&it| it == AssistKind::None || it == AssistKind::QuickFix), | 564 | Some(it) => it.iter().any(|&it| it == AssistKind::None || it == AssistKind::QuickFix), |
565 | None => true, | 565 | None => true, |
@@ -591,14 +591,14 @@ impl Analysis { | |||
591 | &self, | 591 | &self, |
592 | position: FilePosition, | 592 | position: FilePosition, |
593 | new_name: &str, | 593 | new_name: &str, |
594 | ) -> Cancelable<Result<SourceChange, RenameError>> { | 594 | ) -> Cancellable<Result<SourceChange, RenameError>> { |
595 | self.with_db(|db| references::rename::rename(db, position, new_name)) | 595 | self.with_db(|db| references::rename::rename(db, position, new_name)) |
596 | } | 596 | } |
597 | 597 | ||
598 | pub fn prepare_rename( | 598 | pub fn prepare_rename( |
599 | &self, | 599 | &self, |
600 | position: FilePosition, | 600 | position: FilePosition, |
601 | ) -> Cancelable<Result<RangeInfo<()>, RenameError>> { | 601 | ) -> Cancellable<Result<RangeInfo<()>, RenameError>> { |
602 | self.with_db(|db| references::rename::prepare_rename(db, position)) | 602 | self.with_db(|db| references::rename::prepare_rename(db, position)) |
603 | } | 603 | } |
604 | 604 | ||
@@ -606,7 +606,7 @@ impl Analysis { | |||
606 | &self, | 606 | &self, |
607 | file_id: FileId, | 607 | file_id: FileId, |
608 | new_name_stem: &str, | 608 | new_name_stem: &str, |
609 | ) -> Cancelable<Option<SourceChange>> { | 609 | ) -> Cancellable<Option<SourceChange>> { |
610 | self.with_db(|db| references::rename::will_rename_file(db, file_id, new_name_stem)) | 610 | self.with_db(|db| references::rename::will_rename_file(db, file_id, new_name_stem)) |
611 | } | 611 | } |
612 | 612 | ||
@@ -616,7 +616,7 @@ impl Analysis { | |||
616 | parse_only: bool, | 616 | parse_only: bool, |
617 | resolve_context: FilePosition, | 617 | resolve_context: FilePosition, |
618 | selections: Vec<FileRange>, | 618 | selections: Vec<FileRange>, |
619 | ) -> Cancelable<Result<SourceChange, SsrError>> { | 619 | ) -> Cancellable<Result<SourceChange, SsrError>> { |
620 | self.with_db(|db| { | 620 | self.with_db(|db| { |
621 | let rule: ide_ssr::SsrRule = query.parse()?; | 621 | let rule: ide_ssr::SsrRule = query.parse()?; |
622 | let mut match_finder = | 622 | let mut match_finder = |
@@ -631,11 +631,11 @@ impl Analysis { | |||
631 | &self, | 631 | &self, |
632 | file_id: FileId, | 632 | file_id: FileId, |
633 | config: AnnotationConfig, | 633 | config: AnnotationConfig, |
634 | ) -> Cancelable<Vec<Annotation>> { | 634 | ) -> Cancellable<Vec<Annotation>> { |
635 | self.with_db(|db| annotations::annotations(db, file_id, config)) | 635 | self.with_db(|db| annotations::annotations(db, file_id, config)) |
636 | } | 636 | } |
637 | 637 | ||
638 | pub fn resolve_annotation(&self, annotation: Annotation) -> Cancelable<Annotation> { | 638 | pub fn resolve_annotation(&self, annotation: Annotation) -> Cancellable<Annotation> { |
639 | self.with_db(|db| annotations::resolve_annotation(db, annotation)) | 639 | self.with_db(|db| annotations::resolve_annotation(db, annotation)) |
640 | } | 640 | } |
641 | 641 | ||
@@ -643,16 +643,28 @@ impl Analysis { | |||
643 | &self, | 643 | &self, |
644 | range: FileRange, | 644 | range: FileRange, |
645 | direction: Direction, | 645 | direction: Direction, |
646 | ) -> Cancelable<Option<TextEdit>> { | 646 | ) -> Cancellable<Option<TextEdit>> { |
647 | self.with_db(|db| move_item::move_item(db, range, direction)) | 647 | self.with_db(|db| move_item::move_item(db, range, direction)) |
648 | } | 648 | } |
649 | 649 | ||
650 | /// Performs an operation on that may be Canceled. | 650 | /// Performs an operation on the database that may be canceled. |
651 | fn with_db<F, T>(&self, f: F) -> Cancelable<T> | 651 | /// |
652 | /// rust-analyzer needs to be able to answer semantic questions about the | ||
653 | /// code while the code is being modified. A common problem is that a | ||
654 | /// long-running query is being calculated when a new change arrives. | ||
655 | /// | ||
656 | /// We can't just apply the change immediately: this will cause the pending | ||
657 | /// query to see inconsistent state (it will observe an absence of | ||
658 | /// repeatable read). So what we do is we **cancel** all pending queries | ||
659 | /// before applying the change. | ||
660 | /// | ||
661 | /// Salsa implements cancelation by unwinding with a special value and | ||
662 | /// catching it on the API boundary. | ||
663 | fn with_db<F, T>(&self, f: F) -> Cancellable<T> | ||
652 | where | 664 | where |
653 | F: FnOnce(&RootDatabase) -> T + std::panic::UnwindSafe, | 665 | F: FnOnce(&RootDatabase) -> T + std::panic::UnwindSafe, |
654 | { | 666 | { |
655 | self.db.catch_canceled(f) | 667 | Cancelled::catch(|| f(&self.db)) |
656 | } | 668 | } |
657 | } | 669 | } |
658 | 670 | ||
diff --git a/crates/ide_db/src/lib.rs b/crates/ide_db/src/lib.rs index 88ee4a87d..1f900aef4 100644 --- a/crates/ide_db/src/lib.rs +++ b/crates/ide_db/src/lib.rs | |||
@@ -19,8 +19,7 @@ use std::{fmt, sync::Arc}; | |||
19 | 19 | ||
20 | use base_db::{ | 20 | use base_db::{ |
21 | salsa::{self, Durability}, | 21 | salsa::{self, Durability}, |
22 | AnchoredPath, Canceled, CheckCanceled, CrateId, FileId, FileLoader, FileLoaderDelegate, | 22 | AnchoredPath, CrateId, FileId, FileLoader, FileLoaderDelegate, SourceDatabase, Upcast, |
23 | SourceDatabase, Upcast, | ||
24 | }; | 23 | }; |
25 | use hir::db::{AstDatabase, DefDatabase, HirDatabase}; | 24 | use hir::db::{AstDatabase, DefDatabase, HirDatabase}; |
26 | use rustc_hash::FxHashSet; | 25 | use rustc_hash::FxHashSet; |
@@ -80,20 +79,7 @@ impl FileLoader for RootDatabase { | |||
80 | } | 79 | } |
81 | } | 80 | } |
82 | 81 | ||
83 | impl salsa::Database for RootDatabase { | 82 | impl salsa::Database for RootDatabase {} |
84 | fn on_propagated_panic(&self) -> ! { | ||
85 | Canceled::throw() | ||
86 | } | ||
87 | fn salsa_event(&self, event: salsa::Event) { | ||
88 | match event.kind { | ||
89 | salsa::EventKind::DidValidateMemoizedValue { .. } | ||
90 | | salsa::EventKind::WillExecute { .. } => { | ||
91 | self.check_canceled(); | ||
92 | } | ||
93 | _ => (), | ||
94 | } | ||
95 | } | ||
96 | } | ||
97 | 83 | ||
98 | impl Default for RootDatabase { | 84 | impl Default for RootDatabase { |
99 | fn default() -> RootDatabase { | 85 | fn default() -> RootDatabase { |
@@ -126,7 +112,7 @@ impl salsa::ParallelDatabase for RootDatabase { | |||
126 | } | 112 | } |
127 | 113 | ||
128 | #[salsa::query_group(LineIndexDatabaseStorage)] | 114 | #[salsa::query_group(LineIndexDatabaseStorage)] |
129 | pub trait LineIndexDatabase: base_db::SourceDatabase + CheckCanceled { | 115 | pub trait LineIndexDatabase: base_db::SourceDatabase { |
130 | fn line_index(&self, file_id: FileId) -> Arc<LineIndex>; | 116 | fn line_index(&self, file_id: FileId) -> Arc<LineIndex>; |
131 | } | 117 | } |
132 | 118 | ||
diff --git a/crates/ide_db/src/symbol_index.rs b/crates/ide_db/src/symbol_index.rs index 0f5c4abc4..5c372a7e5 100644 --- a/crates/ide_db/src/symbol_index.rs +++ b/crates/ide_db/src/symbol_index.rs | |||
@@ -127,7 +127,7 @@ fn library_symbols(db: &dyn SymbolsDatabase) -> Arc<FxHashMap<SourceRootId, Symb | |||
127 | } | 127 | } |
128 | 128 | ||
129 | fn file_symbols(db: &dyn SymbolsDatabase, file_id: FileId) -> Arc<SymbolIndex> { | 129 | fn file_symbols(db: &dyn SymbolsDatabase, file_id: FileId) -> Arc<SymbolIndex> { |
130 | db.check_canceled(); | 130 | db.unwind_if_cancelled(); |
131 | let parse = db.parse(file_id); | 131 | let parse = db.parse(file_id); |
132 | 132 | ||
133 | let symbols = source_file_to_file_symbols(&parse.tree(), file_id); | 133 | let symbols = source_file_to_file_symbols(&parse.tree(), file_id); |
diff --git a/crates/rust-analyzer/src/dispatch.rs b/crates/rust-analyzer/src/dispatch.rs index baf2199d9..2011a4132 100644 --- a/crates/rust-analyzer/src/dispatch.rs +++ b/crates/rust-analyzer/src/dispatch.rs | |||
@@ -5,7 +5,7 @@ use serde::{de::DeserializeOwned, Serialize}; | |||
5 | 5 | ||
6 | use crate::{ | 6 | use crate::{ |
7 | global_state::{GlobalState, GlobalStateSnapshot}, | 7 | global_state::{GlobalState, GlobalStateSnapshot}, |
8 | lsp_utils::is_canceled, | 8 | lsp_utils::is_cancelled, |
9 | main_loop::Task, | 9 | main_loop::Task, |
10 | LspError, Result, | 10 | LspError, Result, |
11 | }; | 11 | }; |
@@ -132,7 +132,7 @@ where | |||
132 | Err(e) => match e.downcast::<LspError>() { | 132 | Err(e) => match e.downcast::<LspError>() { |
133 | Ok(lsp_error) => lsp_server::Response::new_err(id, lsp_error.code, lsp_error.message), | 133 | Ok(lsp_error) => lsp_server::Response::new_err(id, lsp_error.code, lsp_error.message), |
134 | Err(e) => { | 134 | Err(e) => { |
135 | if is_canceled(&*e) { | 135 | if is_cancelled(&*e) { |
136 | lsp_server::Response::new_err( | 136 | lsp_server::Response::new_err( |
137 | id, | 137 | id, |
138 | lsp_server::ErrorCode::ContentModified as i32, | 138 | lsp_server::ErrorCode::ContentModified as i32, |
diff --git a/crates/rust-analyzer/src/global_state.rs b/crates/rust-analyzer/src/global_state.rs index 6a36d29d4..ea9dbf7fc 100644 --- a/crates/rust-analyzer/src/global_state.rs +++ b/crates/rust-analyzer/src/global_state.rs | |||
@@ -7,7 +7,7 @@ use std::{sync::Arc, time::Instant}; | |||
7 | 7 | ||
8 | use crossbeam_channel::{unbounded, Receiver, Sender}; | 8 | use crossbeam_channel::{unbounded, Receiver, Sender}; |
9 | use flycheck::FlycheckHandle; | 9 | use flycheck::FlycheckHandle; |
10 | use ide::{Analysis, AnalysisHost, Cancelable, Change, FileId}; | 10 | use ide::{Analysis, AnalysisHost, Cancellable, Change, FileId}; |
11 | use ide_db::base_db::{CrateId, VfsPath}; | 11 | use ide_db::base_db::{CrateId, VfsPath}; |
12 | use lsp_types::{SemanticTokens, Url}; | 12 | use lsp_types::{SemanticTokens, Url}; |
13 | use parking_lot::{Mutex, RwLock}; | 13 | use parking_lot::{Mutex, RwLock}; |
@@ -280,7 +280,7 @@ impl GlobalStateSnapshot { | |||
280 | file_id_to_url(&self.vfs.read().0, id) | 280 | file_id_to_url(&self.vfs.read().0, id) |
281 | } | 281 | } |
282 | 282 | ||
283 | pub(crate) fn file_line_index(&self, file_id: FileId) -> Cancelable<LineIndex> { | 283 | pub(crate) fn file_line_index(&self, file_id: FileId) -> Cancellable<LineIndex> { |
284 | let endings = self.vfs.read().1[&file_id]; | 284 | let endings = self.vfs.read().1[&file_id]; |
285 | let index = self.analysis.file_line_index(file_id)?; | 285 | let index = self.analysis.file_line_index(file_id)?; |
286 | let res = LineIndex { index, endings, encoding: self.config.offset_encoding() }; | 286 | let res = LineIndex { index, endings, encoding: self.config.offset_encoding() }; |
diff --git a/crates/rust-analyzer/src/lsp_utils.rs b/crates/rust-analyzer/src/lsp_utils.rs index 73c4193e8..8000b5490 100644 --- a/crates/rust-analyzer/src/lsp_utils.rs +++ b/crates/rust-analyzer/src/lsp_utils.rs | |||
@@ -1,7 +1,7 @@ | |||
1 | //! Utilities for LSP-related boilerplate code. | 1 | //! Utilities for LSP-related boilerplate code. |
2 | use std::{error::Error, ops::Range, sync::Arc}; | 2 | use std::{error::Error, ops::Range, sync::Arc}; |
3 | 3 | ||
4 | use ide_db::base_db::Canceled; | 4 | use ide_db::base_db::Cancelled; |
5 | use lsp_server::Notification; | 5 | use lsp_server::Notification; |
6 | 6 | ||
7 | use crate::{ | 7 | use crate::{ |
@@ -10,8 +10,8 @@ use crate::{ | |||
10 | line_index::{LineEndings, LineIndex, OffsetEncoding}, | 10 | line_index::{LineEndings, LineIndex, OffsetEncoding}, |
11 | }; | 11 | }; |
12 | 12 | ||
13 | pub(crate) fn is_canceled(e: &(dyn Error + 'static)) -> bool { | 13 | pub(crate) fn is_cancelled(e: &(dyn Error + 'static)) -> bool { |
14 | e.downcast_ref::<Canceled>().is_some() | 14 | e.downcast_ref::<Cancelled>().is_some() |
15 | } | 15 | } |
16 | 16 | ||
17 | pub(crate) fn notification_is<N: lsp_types::notification::Notification>( | 17 | pub(crate) fn notification_is<N: lsp_types::notification::Notification>( |
diff --git a/crates/rust-analyzer/src/main_loop.rs b/crates/rust-analyzer/src/main_loop.rs index 008758ea0..31d8ea9e7 100644 --- a/crates/rust-analyzer/src/main_loop.rs +++ b/crates/rust-analyzer/src/main_loop.rs | |||
@@ -22,7 +22,7 @@ use crate::{ | |||
22 | from_proto, | 22 | from_proto, |
23 | global_state::{file_id_to_url, url_to_file_id, GlobalState}, | 23 | global_state::{file_id_to_url, url_to_file_id, GlobalState}, |
24 | handlers, lsp_ext, | 24 | handlers, lsp_ext, |
25 | lsp_utils::{apply_document_changes, is_canceled, notification_is, Progress}, | 25 | lsp_utils::{apply_document_changes, is_cancelled, notification_is, Progress}, |
26 | reload::{BuildDataProgress, ProjectWorkspaceProgress}, | 26 | reload::{BuildDataProgress, ProjectWorkspaceProgress}, |
27 | Result, | 27 | Result, |
28 | }; | 28 | }; |
@@ -752,7 +752,7 @@ impl GlobalState { | |||
752 | .filter_map(|file_id| { | 752 | .filter_map(|file_id| { |
753 | handlers::publish_diagnostics(&snapshot, file_id) | 753 | handlers::publish_diagnostics(&snapshot, file_id) |
754 | .map_err(|err| { | 754 | .map_err(|err| { |
755 | if !is_canceled(&*err) { | 755 | if !is_cancelled(&*err) { |
756 | log::error!("failed to compute diagnostics: {:?}", err); | 756 | log::error!("failed to compute diagnostics: {:?}", err); |
757 | } | 757 | } |
758 | () | 758 | () |
diff --git a/crates/rust-analyzer/src/to_proto.rs b/crates/rust-analyzer/src/to_proto.rs index 6d18d0ffc..411f6baa9 100644 --- a/crates/rust-analyzer/src/to_proto.rs +++ b/crates/rust-analyzer/src/to_proto.rs | |||
@@ -6,7 +6,7 @@ use std::{ | |||
6 | }; | 6 | }; |
7 | 7 | ||
8 | use ide::{ | 8 | use ide::{ |
9 | Annotation, AnnotationKind, Assist, AssistKind, CallInfo, Cancelable, CompletionItem, | 9 | Annotation, AnnotationKind, Assist, AssistKind, CallInfo, Cancellable, CompletionItem, |
10 | CompletionItemKind, CompletionRelevance, Documentation, FileId, FileRange, FileSystemEdit, | 10 | CompletionItemKind, CompletionRelevance, Documentation, FileId, FileRange, FileSystemEdit, |
11 | Fold, FoldKind, Highlight, HlMod, HlOperator, HlPunct, HlRange, HlTag, Indel, InlayHint, | 11 | Fold, FoldKind, Highlight, HlMod, HlOperator, HlPunct, HlRange, HlTag, Indel, InlayHint, |
12 | InlayKind, InsertTextFormat, Markup, NavigationTarget, ReferenceAccess, RenameError, Runnable, | 12 | InlayKind, InsertTextFormat, Markup, NavigationTarget, ReferenceAccess, RenameError, Runnable, |
@@ -726,7 +726,7 @@ pub(crate) fn snippet_text_document_edit( | |||
726 | pub(crate) fn snippet_text_document_ops( | 726 | pub(crate) fn snippet_text_document_ops( |
727 | snap: &GlobalStateSnapshot, | 727 | snap: &GlobalStateSnapshot, |
728 | file_system_edit: FileSystemEdit, | 728 | file_system_edit: FileSystemEdit, |
729 | ) -> Cancelable<Vec<lsp_ext::SnippetDocumentChangeOperation>> { | 729 | ) -> Cancellable<Vec<lsp_ext::SnippetDocumentChangeOperation>> { |
730 | let mut ops = Vec::new(); | 730 | let mut ops = Vec::new(); |
731 | match file_system_edit { | 731 | match file_system_edit { |
732 | FileSystemEdit::CreateFile { dst, initial_contents } => { | 732 | FileSystemEdit::CreateFile { dst, initial_contents } => { |
@@ -756,7 +756,7 @@ pub(crate) fn snippet_text_document_ops( | |||
756 | let new_uri = snap.anchored_path(&dst); | 756 | let new_uri = snap.anchored_path(&dst); |
757 | let mut rename_file = | 757 | let mut rename_file = |
758 | lsp_types::RenameFile { old_uri, new_uri, options: None, annotation_id: None }; | 758 | lsp_types::RenameFile { old_uri, new_uri, options: None, annotation_id: None }; |
759 | if snap.analysis.is_library_file(src) == Ok(true) | 759 | if snap.analysis.is_library_file(src).ok() == Some(true) |
760 | && snap.config.change_annotation_support() | 760 | && snap.config.change_annotation_support() |
761 | { | 761 | { |
762 | rename_file.annotation_id = Some(outside_workspace_annotation_id()) | 762 | rename_file.annotation_id = Some(outside_workspace_annotation_id()) |