diff options
Diffstat (limited to 'crates')
-rw-r--r-- | crates/ra_db/src/cancellation.rs | 6 | ||||
-rw-r--r-- | crates/ra_db/src/lib.rs | 22 | ||||
-rw-r--r-- | crates/ra_db/src/loc2id.rs | 11 | ||||
-rw-r--r-- | crates/ra_hir/src/mock.rs | 4 | ||||
-rw-r--r-- | crates/ra_ide_api/src/db.rs | 5 | ||||
-rw-r--r-- | crates/ra_ide_api/src/lib.rs | 51 |
6 files changed, 72 insertions, 27 deletions
diff --git a/crates/ra_db/src/cancellation.rs b/crates/ra_db/src/cancellation.rs index 8d38eebfb..32a268553 100644 --- a/crates/ra_db/src/cancellation.rs +++ b/crates/ra_db/src/cancellation.rs | |||
@@ -27,6 +27,12 @@ impl Canceled { | |||
27 | pub(crate) fn new() -> Canceled { | 27 | pub(crate) fn new() -> Canceled { |
28 | Canceled { _private: () } | 28 | Canceled { _private: () } |
29 | } | 29 | } |
30 | |||
31 | pub fn throw() -> ! { | ||
32 | // We use resume and not panic here to avoid running the panic | ||
33 | // hook (that is, to avoid collecting and printing backtrace). | ||
34 | std::panic::resume_unwind(Box::new(Canceled::new())) | ||
35 | } | ||
30 | } | 36 | } |
31 | 37 | ||
32 | impl std::fmt::Display for Canceled { | 38 | impl std::fmt::Display for Canceled { |
diff --git a/crates/ra_db/src/lib.rs b/crates/ra_db/src/lib.rs index fb8ea2496..20e712afe 100644 --- a/crates/ra_db/src/lib.rs +++ b/crates/ra_db/src/lib.rs | |||
@@ -5,6 +5,8 @@ mod input; | |||
5 | mod loc2id; | 5 | mod loc2id; |
6 | pub mod mock; | 6 | pub mod mock; |
7 | 7 | ||
8 | use std::panic; | ||
9 | |||
8 | use ra_syntax::{TextUnit, TextRange, SourceFile, TreePtr}; | 10 | use ra_syntax::{TextUnit, TextRange, SourceFile, TreePtr}; |
9 | 11 | ||
10 | pub use crate::{ | 12 | pub use crate::{ |
@@ -18,13 +20,21 @@ pub use crate::{ | |||
18 | loc2id::LocationIntener, | 20 | loc2id::LocationIntener, |
19 | }; | 21 | }; |
20 | 22 | ||
21 | pub trait BaseDatabase: salsa::Database { | 23 | pub trait BaseDatabase: salsa::Database + panic::RefUnwindSafe { |
22 | fn check_canceled(&self) -> Cancelable<()> { | 24 | fn check_canceled(&self) -> Cancelable<()> { |
23 | if self.salsa_runtime().is_current_revision_canceled() { | 25 | self.salsa_runtime() |
24 | Err(Canceled::new()) | 26 | .if_current_revision_is_canceled(Canceled::throw); |
25 | } else { | 27 | Ok(()) |
26 | Ok(()) | 28 | } |
27 | } | 29 | |
30 | fn catch_canceled<F: FnOnce(&Self) -> T + panic::UnwindSafe, T>( | ||
31 | &self, | ||
32 | f: F, | ||
33 | ) -> Result<T, Canceled> { | ||
34 | panic::catch_unwind(|| f(self)).map_err(|err| match err.downcast::<Canceled>() { | ||
35 | Ok(canceled) => *canceled, | ||
36 | Err(payload) => panic::resume_unwind(payload), | ||
37 | }) | ||
28 | } | 38 | } |
29 | } | 39 | } |
30 | 40 | ||
diff --git a/crates/ra_db/src/loc2id.rs b/crates/ra_db/src/loc2id.rs index 254c52629..359cd893d 100644 --- a/crates/ra_db/src/loc2id.rs +++ b/crates/ra_db/src/loc2id.rs | |||
@@ -1,4 +1,4 @@ | |||
1 | use std::hash::Hash; | 1 | use std::{panic, hash::Hash}; |
2 | 2 | ||
3 | use parking_lot::Mutex; | 3 | use parking_lot::Mutex; |
4 | use rustc_hash::FxHashMap; | 4 | use rustc_hash::FxHashMap; |
@@ -70,6 +70,15 @@ where | |||
70 | map: Mutex<Loc2IdMap<LOC, ID>>, | 70 | map: Mutex<Loc2IdMap<LOC, ID>>, |
71 | } | 71 | } |
72 | 72 | ||
73 | impl<LOC, ID> panic::RefUnwindSafe for LocationIntener<LOC, ID> | ||
74 | where | ||
75 | ID: ArenaId + Clone, | ||
76 | LOC: Clone + Eq + Hash, | ||
77 | ID: panic::RefUnwindSafe, | ||
78 | LOC: panic::RefUnwindSafe, | ||
79 | { | ||
80 | } | ||
81 | |||
73 | impl<LOC, ID> Default for LocationIntener<LOC, ID> | 82 | impl<LOC, ID> Default for LocationIntener<LOC, ID> |
74 | where | 83 | where |
75 | ID: ArenaId + Clone, | 84 | ID: ArenaId + Clone, |
diff --git a/crates/ra_hir/src/mock.rs b/crates/ra_hir/src/mock.rs index 0fae7de82..7a0301648 100644 --- a/crates/ra_hir/src/mock.rs +++ b/crates/ra_hir/src/mock.rs | |||
@@ -1,4 +1,4 @@ | |||
1 | use std::sync::Arc; | 1 | use std::{sync::Arc, panic}; |
2 | 2 | ||
3 | use parking_lot::Mutex; | 3 | use parking_lot::Mutex; |
4 | use salsa::{self, Database}; | 4 | use salsa::{self, Database}; |
@@ -18,6 +18,8 @@ pub(crate) struct MockDatabase { | |||
18 | file_counter: u32, | 18 | file_counter: u32, |
19 | } | 19 | } |
20 | 20 | ||
21 | impl panic::RefUnwindSafe for MockDatabase {} | ||
22 | |||
21 | impl MockDatabase { | 23 | impl MockDatabase { |
22 | pub(crate) fn with_files(fixture: &str) -> (MockDatabase, SourceRoot) { | 24 | pub(crate) fn with_files(fixture: &str) -> (MockDatabase, SourceRoot) { |
23 | let (db, source_root, position) = MockDatabase::from_fixture(fixture); | 25 | let (db, source_root, position) = MockDatabase::from_fixture(fixture); |
diff --git a/crates/ra_ide_api/src/db.rs b/crates/ra_ide_api/src/db.rs index 9d46609ec..a2e06f5db 100644 --- a/crates/ra_ide_api/src/db.rs +++ b/crates/ra_ide_api/src/db.rs | |||
@@ -1,7 +1,7 @@ | |||
1 | use std::{fmt, sync::Arc}; | 1 | use std::{fmt, sync::Arc}; |
2 | 2 | ||
3 | use salsa::{self, Database}; | 3 | use salsa::{self, Database}; |
4 | use ra_db::{LocationIntener, BaseDatabase, FileId}; | 4 | use ra_db::{LocationIntener, BaseDatabase, FileId, Canceled}; |
5 | 5 | ||
6 | use crate::{symbol_index, LineIndex}; | 6 | use crate::{symbol_index, LineIndex}; |
7 | 7 | ||
@@ -29,6 +29,9 @@ impl salsa::Database for RootDatabase { | |||
29 | fn salsa_runtime(&self) -> &salsa::Runtime<RootDatabase> { | 29 | fn salsa_runtime(&self) -> &salsa::Runtime<RootDatabase> { |
30 | &self.runtime | 30 | &self.runtime |
31 | } | 31 | } |
32 | fn on_propagated_panic(&self) -> ! { | ||
33 | Canceled::throw() | ||
34 | } | ||
32 | } | 35 | } |
33 | 36 | ||
34 | impl Default for RootDatabase { | 37 | impl Default for RootDatabase { |
diff --git a/crates/ra_ide_api/src/lib.rs b/crates/ra_ide_api/src/lib.rs index fbe1421a4..f505959ce 100644 --- a/crates/ra_ide_api/src/lib.rs +++ b/crates/ra_ide_api/src/lib.rs | |||
@@ -35,7 +35,7 @@ use std::{fmt, sync::Arc}; | |||
35 | 35 | ||
36 | use ra_syntax::{SmolStr, SourceFile, TreePtr, SyntaxKind, TextRange, TextUnit}; | 36 | use ra_syntax::{SmolStr, SourceFile, TreePtr, SyntaxKind, TextRange, TextUnit}; |
37 | use ra_text_edit::TextEdit; | 37 | use ra_text_edit::TextEdit; |
38 | use ra_db::{SyntaxDatabase, FilesDatabase, LocalSyntaxPtr}; | 38 | use ra_db::{SyntaxDatabase, FilesDatabase, LocalSyntaxPtr, BaseDatabase}; |
39 | use rayon::prelude::*; | 39 | use rayon::prelude::*; |
40 | use relative_path::RelativePathBuf; | 40 | use relative_path::RelativePathBuf; |
41 | use rustc_hash::FxHashMap; | 41 | use rustc_hash::FxHashMap; |
@@ -420,43 +420,47 @@ impl Analysis { | |||
420 | 420 | ||
421 | /// Fuzzy searches for a symbol. | 421 | /// Fuzzy searches for a symbol. |
422 | pub fn symbol_search(&self, query: Query) -> Cancelable<Vec<NavigationTarget>> { | 422 | pub fn symbol_search(&self, query: Query) -> Cancelable<Vec<NavigationTarget>> { |
423 | let res = symbol_index::world_symbols(&*self.db, query)? | 423 | self.with_db(|db| { |
424 | .into_iter() | 424 | let res = symbol_index::world_symbols(db, query)? |
425 | .map(NavigationTarget::from_symbol) | 425 | .into_iter() |
426 | .collect(); | 426 | .map(NavigationTarget::from_symbol) |
427 | Ok(res) | 427 | .collect::<Vec<_>>(); |
428 | Ok(res) | ||
429 | })? | ||
428 | } | 430 | } |
429 | 431 | ||
430 | pub fn goto_definition( | 432 | pub fn goto_definition( |
431 | &self, | 433 | &self, |
432 | position: FilePosition, | 434 | position: FilePosition, |
433 | ) -> Cancelable<Option<Vec<NavigationTarget>>> { | 435 | ) -> Cancelable<Option<Vec<NavigationTarget>>> { |
434 | goto_definition::goto_definition(&*self.db, position) | 436 | self.db |
437 | .catch_canceled(|db| goto_definition::goto_definition(db, position))? | ||
435 | } | 438 | } |
436 | 439 | ||
437 | /// Finds all usages of the reference at point. | 440 | /// Finds all usages of the reference at point. |
438 | pub fn find_all_refs(&self, position: FilePosition) -> Cancelable<Vec<(FileId, TextRange)>> { | 441 | pub fn find_all_refs(&self, position: FilePosition) -> Cancelable<Vec<(FileId, TextRange)>> { |
439 | self.db.find_all_refs(position) | 442 | self.with_db(|db| db.find_all_refs(position))? |
440 | } | 443 | } |
441 | 444 | ||
442 | /// Returns a short text descrbing element at position. | 445 | /// Returns a short text descrbing element at position. |
443 | pub fn hover(&self, position: FilePosition) -> Cancelable<Option<RangeInfo<String>>> { | 446 | pub fn hover(&self, position: FilePosition) -> Cancelable<Option<RangeInfo<String>>> { |
444 | hover::hover(&*self.db, position) | 447 | self.with_db(|db| hover::hover(db, position))? |
445 | } | 448 | } |
446 | 449 | ||
447 | /// Computes parameter information for the given call expression. | 450 | /// Computes parameter information for the given call expression. |
448 | pub fn call_info(&self, position: FilePosition) -> Cancelable<Option<CallInfo>> { | 451 | pub fn call_info(&self, position: FilePosition) -> Cancelable<Option<CallInfo>> { |
449 | call_info::call_info(&*self.db, position) | 452 | self.db |
453 | .catch_canceled(|db| call_info::call_info(db, position))? | ||
450 | } | 454 | } |
451 | 455 | ||
452 | /// Returns a `mod name;` declaration which created the current module. | 456 | /// Returns a `mod name;` declaration which created the current module. |
453 | pub fn parent_module(&self, position: FilePosition) -> Cancelable<Vec<NavigationTarget>> { | 457 | pub fn parent_module(&self, position: FilePosition) -> Cancelable<Vec<NavigationTarget>> { |
454 | self.db.parent_module(position) | 458 | self.with_db(|db| db.parent_module(position))? |
455 | } | 459 | } |
456 | 460 | ||
457 | /// Returns crates this file belongs too. | 461 | /// Returns crates this file belongs too. |
458 | pub fn crate_for(&self, file_id: FileId) -> Cancelable<Vec<CrateId>> { | 462 | pub fn crate_for(&self, file_id: FileId) -> Cancelable<Vec<CrateId>> { |
459 | self.db.crate_for(file_id) | 463 | self.with_db(|db| db.crate_for(file_id))? |
460 | } | 464 | } |
461 | 465 | ||
462 | /// Returns the root file of the given crate. | 466 | /// Returns the root file of the given crate. |
@@ -466,17 +470,21 @@ impl Analysis { | |||
466 | 470 | ||
467 | /// Returns the set of possible targets to run for the current file. | 471 | /// Returns the set of possible targets to run for the current file. |
468 | pub fn runnables(&self, file_id: FileId) -> Cancelable<Vec<Runnable>> { | 472 | pub fn runnables(&self, file_id: FileId) -> Cancelable<Vec<Runnable>> { |
469 | runnables::runnables(&*self.db, file_id) | 473 | self.db |
474 | .catch_canceled(|db| runnables::runnables(db, file_id))? | ||
470 | } | 475 | } |
471 | 476 | ||
472 | /// Computes syntax highlighting for the given file. | 477 | /// Computes syntax highlighting for the given file. |
473 | pub fn highlight(&self, file_id: FileId) -> Cancelable<Vec<HighlightedRange>> { | 478 | pub fn highlight(&self, file_id: FileId) -> Cancelable<Vec<HighlightedRange>> { |
474 | syntax_highlighting::highlight(&*self.db, file_id) | 479 | self.db |
480 | .catch_canceled(|db| syntax_highlighting::highlight(db, file_id))? | ||
475 | } | 481 | } |
476 | 482 | ||
477 | /// Computes completions at the given position. | 483 | /// Computes completions at the given position. |
478 | pub fn completions(&self, position: FilePosition) -> Cancelable<Option<Vec<CompletionItem>>> { | 484 | pub fn completions(&self, position: FilePosition) -> Cancelable<Option<Vec<CompletionItem>>> { |
479 | let completions = completion::completions(&self.db, position)?; | 485 | let completions = self |
486 | .db | ||
487 | .catch_canceled(|db| completion::completions(db, position))??; | ||
480 | Ok(completions.map(|it| it.into())) | 488 | Ok(completions.map(|it| it.into())) |
481 | } | 489 | } |
482 | 490 | ||
@@ -488,12 +496,12 @@ impl Analysis { | |||
488 | 496 | ||
489 | /// Computes the set of diagnostics for the given file. | 497 | /// Computes the set of diagnostics for the given file. |
490 | pub fn diagnostics(&self, file_id: FileId) -> Cancelable<Vec<Diagnostic>> { | 498 | pub fn diagnostics(&self, file_id: FileId) -> Cancelable<Vec<Diagnostic>> { |
491 | self.db.diagnostics(file_id) | 499 | self.with_db(|db| db.diagnostics(file_id))? |
492 | } | 500 | } |
493 | 501 | ||
494 | /// Computes the type of the expression at the given position. | 502 | /// Computes the type of the expression at the given position. |
495 | pub fn type_of(&self, frange: FileRange) -> Cancelable<Option<String>> { | 503 | pub fn type_of(&self, frange: FileRange) -> Cancelable<Option<String>> { |
496 | hover::type_of(&*self.db, frange) | 504 | self.with_db(|db| hover::type_of(db, frange))? |
497 | } | 505 | } |
498 | 506 | ||
499 | /// Returns the edit required to rename reference at the position to the new | 507 | /// Returns the edit required to rename reference at the position to the new |
@@ -503,7 +511,14 @@ impl Analysis { | |||
503 | position: FilePosition, | 511 | position: FilePosition, |
504 | new_name: &str, | 512 | new_name: &str, |
505 | ) -> Cancelable<Vec<SourceFileEdit>> { | 513 | ) -> Cancelable<Vec<SourceFileEdit>> { |
506 | self.db.rename(position, new_name) | 514 | self.with_db(|db| db.rename(position, new_name))? |
515 | } | ||
516 | |||
517 | fn with_db<F: FnOnce(&db::RootDatabase) -> T + std::panic::UnwindSafe, T>( | ||
518 | &self, | ||
519 | f: F, | ||
520 | ) -> Cancelable<T> { | ||
521 | self.db.catch_canceled(f) | ||
507 | } | 522 | } |
508 | } | 523 | } |
509 | 524 | ||