diff options
author | bors[bot] <bors[bot]@users.noreply.github.com> | 2019-02-03 19:15:56 +0000 |
---|---|---|
committer | bors[bot] <bors[bot]@users.noreply.github.com> | 2019-02-03 19:15:56 +0000 |
commit | 998ed13d09992d1fe24a45cc725c55390d9a5ca7 (patch) | |
tree | 0b2388011e628c6a1ff6d7cbca0664ba00dfe4f5 | |
parent | 395965351d467c716f259935557117fe42a8c9f4 (diff) | |
parent | dbf9820e35cf2d96bd3295e6890e8ef1cb0a060a (diff) |
Merge #735
735: make HirDatabase object-safe r=matklad a=matklad
Co-authored-by: Aleksey Kladov <[email protected]>
-rw-r--r-- | crates/ra_db/src/lib.rs | 27 | ||||
-rw-r--r-- | crates/ra_hir/src/db.rs | 5 | ||||
-rw-r--r-- | crates/ra_hir/src/mock.rs | 4 | ||||
-rw-r--r-- | crates/ra_ide_api/src/db.rs | 2 | ||||
-rw-r--r-- | crates/ra_ide_api/src/lib.rs | 4 |
5 files changed, 26 insertions, 16 deletions
diff --git a/crates/ra_db/src/lib.rs b/crates/ra_db/src/lib.rs index ca775030d..926cf0bd5 100644 --- a/crates/ra_db/src/lib.rs +++ b/crates/ra_db/src/lib.rs | |||
@@ -19,7 +19,7 @@ pub use crate::{ | |||
19 | loc2id::LocationIntener, | 19 | loc2id::LocationIntener, |
20 | }; | 20 | }; |
21 | 21 | ||
22 | pub trait CheckCanceled: salsa::Database + panic::RefUnwindSafe { | 22 | pub trait CheckCanceled: panic::RefUnwindSafe { |
23 | /// Aborts current query if there are pending changes. | 23 | /// Aborts current query if there are pending changes. |
24 | /// | 24 | /// |
25 | /// rust-analyzer needs to be able to answer semantic questions about the | 25 | /// rust-analyzer needs to be able to answer semantic questions about the |
@@ -33,16 +33,13 @@ pub trait CheckCanceled: salsa::Database + panic::RefUnwindSafe { | |||
33 | /// | 33 | /// |
34 | /// We implement cancellation by panicking with a special value and catching | 34 | /// We implement cancellation by panicking with a special value and catching |
35 | /// it on the API boundary. Salsa explicitly supports this use-case. | 35 | /// it on the API boundary. Salsa explicitly supports this use-case. |
36 | fn check_canceled(&self) { | 36 | fn check_canceled(&self); |
37 | if self.salsa_runtime().is_current_revision_canceled() { | ||
38 | Canceled::throw() | ||
39 | } | ||
40 | } | ||
41 | 37 | ||
42 | fn catch_canceled<F: FnOnce(&Self) -> T + panic::UnwindSafe, T>( | 38 | fn catch_canceled<F, T>(&self, f: F) -> Result<T, Canceled> |
43 | &self, | 39 | where |
44 | f: F, | 40 | Self: Sized, |
45 | ) -> Result<T, Canceled> { | 41 | F: FnOnce(&Self) -> T + panic::UnwindSafe, |
42 | { | ||
46 | panic::catch_unwind(|| f(self)).map_err(|err| match err.downcast::<Canceled>() { | 43 | panic::catch_unwind(|| f(self)).map_err(|err| match err.downcast::<Canceled>() { |
47 | Ok(canceled) => *canceled, | 44 | Ok(canceled) => *canceled, |
48 | Err(payload) => panic::resume_unwind(payload), | 45 | Err(payload) => panic::resume_unwind(payload), |
@@ -50,6 +47,14 @@ pub trait CheckCanceled: salsa::Database + panic::RefUnwindSafe { | |||
50 | } | 47 | } |
51 | } | 48 | } |
52 | 49 | ||
50 | impl<T: salsa::Database + panic::RefUnwindSafe> CheckCanceled for T { | ||
51 | fn check_canceled(&self) { | ||
52 | if self.salsa_runtime().is_current_revision_canceled() { | ||
53 | Canceled::throw() | ||
54 | } | ||
55 | } | ||
56 | } | ||
57 | |||
53 | #[derive(Clone, Copy, Debug)] | 58 | #[derive(Clone, Copy, Debug)] |
54 | pub struct FilePosition { | 59 | pub struct FilePosition { |
55 | pub file_id: FileId, | 60 | pub file_id: FileId, |
@@ -65,7 +70,7 @@ pub struct FileRange { | |||
65 | /// Database which stores all significant input facts: source code and project | 70 | /// Database which stores all significant input facts: source code and project |
66 | /// model. Everything else in rust-analyzer is derived from these queries. | 71 | /// model. Everything else in rust-analyzer is derived from these queries. |
67 | #[salsa::query_group(SourceDatabaseStorage)] | 72 | #[salsa::query_group(SourceDatabaseStorage)] |
68 | pub trait SourceDatabase: salsa::Database + CheckCanceled { | 73 | pub trait SourceDatabase: CheckCanceled { |
69 | /// Text of the file. | 74 | /// Text of the file. |
70 | #[salsa::input] | 75 | #[salsa::input] |
71 | fn file_text(&self, file_id: FileId) -> Arc<String>; | 76 | fn file_text(&self, file_id: FileId) -> Arc<String>; |
diff --git a/crates/ra_hir/src/db.rs b/crates/ra_hir/src/db.rs index 6b21fe744..e03632519 100644 --- a/crates/ra_hir/src/db.rs +++ b/crates/ra_hir/src/db.rs | |||
@@ -103,3 +103,8 @@ pub trait HirDatabase: PersistentHirDatabase { | |||
103 | #[salsa::invoke(crate::ty::method_resolution::CrateImplBlocks::impls_in_crate_query)] | 103 | #[salsa::invoke(crate::ty::method_resolution::CrateImplBlocks::impls_in_crate_query)] |
104 | fn impls_in_crate(&self, krate: Crate) -> Arc<CrateImplBlocks>; | 104 | fn impls_in_crate(&self, krate: Crate) -> Arc<CrateImplBlocks>; |
105 | } | 105 | } |
106 | |||
107 | #[test] | ||
108 | fn hir_database_is_object_safe() { | ||
109 | fn _assert_object_safe(_: &dyn HirDatabase) {} | ||
110 | } | ||
diff --git a/crates/ra_hir/src/mock.rs b/crates/ra_hir/src/mock.rs index 17bdd48c6..00a07d1a1 100644 --- a/crates/ra_hir/src/mock.rs +++ b/crates/ra_hir/src/mock.rs | |||
@@ -2,7 +2,7 @@ use std::{sync::Arc, panic}; | |||
2 | 2 | ||
3 | use parking_lot::Mutex; | 3 | use parking_lot::Mutex; |
4 | use ra_db::{ | 4 | use ra_db::{ |
5 | CheckCanceled, FilePosition, FileId, CrateGraph, SourceRoot, SourceRootId, SourceDatabase, salsa, | 5 | FilePosition, FileId, CrateGraph, SourceRoot, SourceRootId, SourceDatabase, salsa, |
6 | }; | 6 | }; |
7 | use relative_path::RelativePathBuf; | 7 | use relative_path::RelativePathBuf; |
8 | use test_utils::{parse_fixture, CURSOR_MARKER, extract_offset}; | 8 | use test_utils::{parse_fixture, CURSOR_MARKER, extract_offset}; |
@@ -159,8 +159,6 @@ impl salsa::ParallelDatabase for MockDatabase { | |||
159 | } | 159 | } |
160 | } | 160 | } |
161 | 161 | ||
162 | impl CheckCanceled for MockDatabase {} | ||
163 | |||
164 | impl AsRef<HirInterner> for MockDatabase { | 162 | impl AsRef<HirInterner> for MockDatabase { |
165 | fn as_ref(&self) -> &HirInterner { | 163 | fn as_ref(&self) -> &HirInterner { |
166 | &self.interner | 164 | &self.interner |
diff --git a/crates/ra_ide_api/src/db.rs b/crates/ra_ide_api/src/db.rs index 3a9089c22..00f4bdfd2 100644 --- a/crates/ra_ide_api/src/db.rs +++ b/crates/ra_ide_api/src/db.rs | |||
@@ -60,8 +60,6 @@ impl salsa::ParallelDatabase for RootDatabase { | |||
60 | } | 60 | } |
61 | } | 61 | } |
62 | 62 | ||
63 | impl CheckCanceled for RootDatabase {} | ||
64 | |||
65 | impl AsRef<hir::HirInterner> for RootDatabase { | 63 | impl AsRef<hir::HirInterner> for RootDatabase { |
66 | fn as_ref(&self) -> &hir::HirInterner { | 64 | fn as_ref(&self) -> &hir::HirInterner { |
67 | &self.interner | 65 | &self.interner |
diff --git a/crates/ra_ide_api/src/lib.rs b/crates/ra_ide_api/src/lib.rs index a087a2fff..65941a5ca 100644 --- a/crates/ra_ide_api/src/lib.rs +++ b/crates/ra_ide_api/src/lib.rs | |||
@@ -9,6 +9,10 @@ | |||
9 | //! | 9 | //! |
10 | //! The sibling `ra_ide_api_light` handles thouse bits of IDE functionality | 10 | //! The sibling `ra_ide_api_light` handles thouse bits of IDE functionality |
11 | //! which are restricted to a single file and need only syntax. | 11 | //! which are restricted to a single file and need only syntax. |
12 | |||
13 | // For proving that RootDatabase is RefUnwindSafe. | ||
14 | #![recursion_limit = "128"] | ||
15 | |||
12 | mod db; | 16 | mod db; |
13 | mod imp; | 17 | mod imp; |
14 | pub mod mock_analysis; | 18 | pub mod mock_analysis; |