Unnamed repository; edit this file 'description' to name the repository.
-rw-r--r--crates/hir/src/lib.rs7
-rw-r--r--crates/ide-db/src/apply_change.rs12
-rw-r--r--crates/ide-db/src/items_locator.rs4
-rw-r--r--crates/ide-db/src/lib.rs10
-rw-r--r--crates/ide-db/src/prime_caches.rs7
-rw-r--r--crates/ide-db/src/symbol_index.rs154
-rw-r--r--crates/ide-ssr/src/lib.rs6
-rw-r--r--crates/ide-ssr/src/search.rs4
-rw-r--r--crates/ide-ssr/src/tests.rs7
-rw-r--r--crates/ide/src/ssr.rs6
-rw-r--r--crates/rust-analyzer/src/cli/ssr.rs3
11 files changed, 125 insertions, 95 deletions
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs
index f2faf99fc9..bb1741a083 100644
--- a/crates/hir/src/lib.rs
+++ b/crates/hir/src/lib.rs
@@ -35,6 +35,9 @@ pub mod term_search;
mod display;
+#[doc(hidden)]
+pub use hir_def::ModuleId;
+
use std::{
fmt,
mem::discriminant,
@@ -48,8 +51,8 @@ use hir_def::{
AdtId, AssocItemId, AssocItemLoc, AttrDefId, CallableDefId, ConstId, ConstParamId,
CrateRootModuleId, DefWithBodyId, EnumId, EnumVariantId, ExternBlockId, ExternCrateId,
FunctionId, GenericDefId, GenericParamId, HasModule, ImplId, ItemContainerId, LifetimeParamId,
- LocalFieldId, Lookup, MacroExpander, MacroId, ModuleId, StaticId, StructId, SyntheticSyntax,
- TupleId, TypeAliasId, TypeOrConstParamId, TypeParamId, UnionId,
+ LocalFieldId, Lookup, MacroExpander, MacroId, StaticId, StructId, SyntheticSyntax, TupleId,
+ TypeAliasId, TypeOrConstParamId, TypeParamId, UnionId,
expr_store::{ExpressionStoreDiagnostics, ExpressionStoreSourceMap},
hir::{
BindingAnnotation, BindingId, Expr, ExprId, ExprOrPatId, LabelId, Pat,
diff --git a/crates/ide-db/src/apply_change.rs b/crates/ide-db/src/apply_change.rs
index 008b6fdbe2..6a85c6e548 100644
--- a/crates/ide-db/src/apply_change.rs
+++ b/crates/ide-db/src/apply_change.rs
@@ -3,10 +3,12 @@
use base_db::SourceRootId;
use profile::Bytes;
use rustc_hash::FxHashSet;
-use salsa::{Database as _, Durability};
-use triomphe::Arc;
+use salsa::{Database as _, Durability, Setter as _};
-use crate::{ChangeWithProcMacros, RootDatabase, symbol_index::SymbolsDatabase};
+use crate::{
+ ChangeWithProcMacros, RootDatabase,
+ symbol_index::{LibraryRoots, LocalRoots},
+};
impl RootDatabase {
pub fn request_cancellation(&mut self) {
@@ -29,8 +31,8 @@ impl RootDatabase {
local_roots.insert(root_id);
}
}
- self.set_local_roots_with_durability(Arc::new(local_roots), Durability::MEDIUM);
- self.set_library_roots_with_durability(Arc::new(library_roots), Durability::MEDIUM);
+ LocalRoots::get(self).set_roots(self).to(local_roots);
+ LibraryRoots::get(self).set_roots(self).to(library_roots);
}
change.apply(self);
}
diff --git a/crates/ide-db/src/items_locator.rs b/crates/ide-db/src/items_locator.rs
index 4b0a84a559..0d305530d9 100644
--- a/crates/ide-db/src/items_locator.rs
+++ b/crates/ide-db/src/items_locator.rs
@@ -10,7 +10,7 @@ use hir::{Complete, Crate, ItemInNs, Module, import_map};
use crate::{
RootDatabase,
imports::import_assets::NameToImport,
- symbol_index::{self, SymbolsDatabase as _},
+ symbol_index::{self, SymbolIndex},
};
/// A value to use, when uncertain which limit to pick.
@@ -110,7 +110,7 @@ pub fn items_with_name_in_module<T>(
local_query
}
};
- local_query.search(&[db.module_symbols(module)], |local_candidate| {
+ local_query.search(&[SymbolIndex::module_symbols(db, module)], |local_candidate| {
cb(match local_candidate.def {
hir::ModuleDef::Macro(macro_def) => ItemInNs::Macros(macro_def),
def => ItemInNs::from(def),
diff --git a/crates/ide-db/src/lib.rs b/crates/ide-db/src/lib.rs
index 7efa97be55..0301b50208 100644
--- a/crates/ide-db/src/lib.rs
+++ b/crates/ide-db/src/lib.rs
@@ -64,7 +64,7 @@ use hir::{
};
use triomphe::Arc;
-use crate::{line_index::LineIndex, symbol_index::SymbolsDatabase};
+use crate::line_index::LineIndex;
pub use rustc_hash::{FxHashMap, FxHashSet, FxHasher};
pub use ::line_index;
@@ -195,8 +195,12 @@ impl RootDatabase {
db.set_all_crates(Arc::new(Box::new([])));
CrateGraphBuilder::default().set_in_db(&mut db);
db.set_proc_macros_with_durability(Default::default(), Durability::MEDIUM);
- db.set_local_roots_with_durability(Default::default(), Durability::MEDIUM);
- db.set_library_roots_with_durability(Default::default(), Durability::MEDIUM);
+ _ = crate::symbol_index::LibraryRoots::builder(Default::default())
+ .durability(Durability::MEDIUM)
+ .new(&db);
+ _ = crate::symbol_index::LocalRoots::builder(Default::default())
+ .durability(Durability::MEDIUM)
+ .new(&db);
db.set_expand_proc_attr_macros_with_durability(false, Durability::HIGH);
db.update_base_query_lru_capacities(lru_capacity);
db
diff --git a/crates/ide-db/src/prime_caches.rs b/crates/ide-db/src/prime_caches.rs
index e6618573e0..1463fdb195 100644
--- a/crates/ide-db/src/prime_caches.rs
+++ b/crates/ide-db/src/prime_caches.rs
@@ -11,7 +11,7 @@ use salsa::{Cancelled, Database};
use crate::{
FxIndexMap, RootDatabase,
base_db::{Crate, RootQueryDb},
- symbol_index::SymbolsDatabase,
+ symbol_index::SymbolIndex,
};
/// We're indexing many crates.
@@ -107,8 +107,9 @@ pub fn parallel_prime_caches(
Ok::<_, crossbeam_channel::SendError<_>>(())
};
let handle_symbols = |module| {
- let cancelled =
- Cancelled::catch(AssertUnwindSafe(|| _ = db.module_symbols(module)));
+ let cancelled = Cancelled::catch(AssertUnwindSafe(|| {
+ _ = SymbolIndex::module_symbols(&db, module)
+ }));
match cancelled {
Ok(()) => progress_sender
diff --git a/crates/ide-db/src/symbol_index.rs b/crates/ide-db/src/symbol_index.rs
index c5ea9bcf5f..ae95883302 100644
--- a/crates/ide-db/src/symbol_index.rs
+++ b/crates/ide-db/src/symbol_index.rs
@@ -27,7 +27,7 @@ use std::{
ops::ControlFlow,
};
-use base_db::{RootQueryDb, SourceDatabase, SourceRootId};
+use base_db::{RootQueryDb, SourceRootId};
use fst::{Automaton, Streamer, raw::IndexedValue};
use hir::{
Crate, Module,
@@ -37,7 +37,6 @@ use hir::{
};
use rayon::prelude::*;
use rustc_hash::FxHashSet;
-use triomphe::Arc;
use crate::RootDatabase;
@@ -102,63 +101,26 @@ impl Query {
}
}
-#[query_group::query_group]
-pub trait SymbolsDatabase: HirDatabase + SourceDatabase {
- /// The symbol index for a given module. These modules should only be in source roots that
- /// are inside local_roots.
- // FIXME: Is it worth breaking the encapsulation boundary of `hir`, and make this take a `ModuleId`,
- // in order for it to be a non-interned query?
- #[salsa::invoke_interned(module_symbols)]
- fn module_symbols(&self, module: Module) -> Arc<SymbolIndex>;
-
- /// The symbol index for a given source root within library_roots.
- #[salsa::invoke_interned(library_symbols)]
- fn library_symbols(&self, source_root_id: SourceRootId) -> Arc<SymbolIndex>;
-
- #[salsa::transparent]
- /// The symbol indices of modules that make up a given crate.
- fn crate_symbols(&self, krate: Crate) -> Box<[Arc<SymbolIndex>]>;
-
- /// The set of "local" (that is, from the current workspace) roots.
- /// Files in local roots are assumed to change frequently.
- #[salsa::input]
- fn local_roots(&self) -> Arc<FxHashSet<SourceRootId>>;
-
- /// The set of roots for crates.io libraries.
- /// Files in libraries are assumed to never change.
- #[salsa::input]
- fn library_roots(&self) -> Arc<FxHashSet<SourceRootId>>;
-}
-
-fn library_symbols(db: &dyn SymbolsDatabase, source_root_id: SourceRootId) -> Arc<SymbolIndex> {
- let _p = tracing::info_span!("library_symbols").entered();
-
- // We call this without attaching because this runs in parallel, so we need to attach here.
- hir::attach_db(db, || {
- let mut symbol_collector = SymbolCollector::new(db);
-
- db.source_root_crates(source_root_id)
- .iter()
- .flat_map(|&krate| Crate::from(krate).modules(db))
- // we specifically avoid calling other SymbolsDatabase queries here, even though they do the same thing,
- // as the index for a library is not going to really ever change, and we do not want to store each
- // the module or crate indices for those in salsa unless we need to.
- .for_each(|module| symbol_collector.collect(module));
-
- Arc::new(SymbolIndex::new(symbol_collector.finish()))
- })
+/// The set of roots for crates.io libraries.
+/// Files in libraries are assumed to never change.
+#[salsa::input(singleton, debug)]
+pub struct LibraryRoots {
+ #[returns(ref)]
+ pub roots: FxHashSet<SourceRootId>,
}
-fn module_symbols(db: &dyn SymbolsDatabase, module: Module) -> Arc<SymbolIndex> {
- let _p = tracing::info_span!("module_symbols").entered();
-
- // We call this without attaching because this runs in parallel, so we need to attach here.
- hir::attach_db(db, || Arc::new(SymbolIndex::new(SymbolCollector::new_module(db, module))))
+/// The set of "local" (that is, from the current workspace) roots.
+/// Files in local roots are assumed to change frequently.
+#[salsa::input(singleton, debug)]
+pub struct LocalRoots {
+ #[returns(ref)]
+ pub roots: FxHashSet<SourceRootId>,
}
-pub fn crate_symbols(db: &dyn SymbolsDatabase, krate: Crate) -> Box<[Arc<SymbolIndex>]> {
+/// The symbol indices of modules that make up a given crate.
+pub fn crate_symbols(db: &dyn HirDatabase, krate: Crate) -> Box<[&SymbolIndex]> {
let _p = tracing::info_span!("crate_symbols").entered();
- krate.modules(db).into_iter().map(|module| db.module_symbols(module)).collect()
+ krate.modules(db).into_iter().map(|module| SymbolIndex::module_symbols(db, module)).collect()
}
// Feature: Workspace Symbol
@@ -190,20 +152,26 @@ pub fn world_symbols(db: &RootDatabase, query: Query) -> Vec<FileSymbol> {
let _p = tracing::info_span!("world_symbols", query = ?query.query).entered();
let indices: Vec<_> = if query.libs {
- db.library_roots()
+ LibraryRoots::get(db)
+ .roots(db)
.par_iter()
- .map_with(db.clone(), |snap, &root| snap.library_symbols(root))
+ .for_each_with(db.clone(), |snap, &root| _ = SymbolIndex::library_symbols(snap, root));
+ LibraryRoots::get(db)
+ .roots(db)
+ .iter()
+ .map(|&root| SymbolIndex::library_symbols(db, root))
.collect()
} else {
let mut crates = Vec::new();
- for &root in db.local_roots().iter() {
+ for &root in LocalRoots::get(db).roots(db).iter() {
crates.extend(db.source_root_crates(root).iter().copied())
}
- let indices: Vec<_> = crates
- .into_par_iter()
- .map_with(db.clone(), |snap, krate| snap.crate_symbols(krate.into()))
- .collect();
+ crates
+ .par_iter()
+ .for_each_with(db.clone(), |snap, &krate| _ = crate_symbols(snap, krate.into()));
+ let indices: Vec<_> =
+ crates.into_iter().map(|krate| crate_symbols(db, krate.into())).collect();
indices.iter().flat_map(|indices| indices.iter().cloned()).collect()
};
@@ -221,6 +189,62 @@ pub struct SymbolIndex {
map: fst::Map<Vec<u8>>,
}
+impl SymbolIndex {
+ /// The symbol index for a given source root within library_roots.
+ pub fn library_symbols(db: &dyn HirDatabase, source_root_id: SourceRootId) -> &SymbolIndex {
+ // FIXME:
+ #[salsa::interned]
+ struct InternedSourceRootId {
+ id: SourceRootId,
+ }
+ #[salsa::tracked(returns(ref))]
+ fn library_symbols(
+ db: &dyn HirDatabase,
+ source_root_id: InternedSourceRootId<'_>,
+ ) -> SymbolIndex {
+ let _p = tracing::info_span!("library_symbols").entered();
+
+ // We call this without attaching because this runs in parallel, so we need to attach here.
+ hir::attach_db(db, || {
+ let mut symbol_collector = SymbolCollector::new(db);
+
+ db.source_root_crates(source_root_id.id(db))
+ .iter()
+ .flat_map(|&krate| Crate::from(krate).modules(db))
+ // we specifically avoid calling other SymbolsDatabase queries here, even though they do the same thing,
+ // as the index for a library is not going to really ever change, and we do not want to store each
+ // the module or crate indices for those in salsa unless we need to.
+ .for_each(|module| symbol_collector.collect(module));
+
+ SymbolIndex::new(symbol_collector.finish())
+ })
+ }
+ library_symbols(db, InternedSourceRootId::new(db, source_root_id))
+ }
+
+ /// The symbol index for a given module. These modules should only be in source roots that
+ /// are inside local_roots.
+ pub fn module_symbols(db: &dyn HirDatabase, module: Module) -> &SymbolIndex {
+ // FIXME:
+ #[salsa::interned]
+ struct InternedModuleId {
+ id: hir::ModuleId,
+ }
+
+ #[salsa::tracked(returns(ref))]
+ fn module_symbols(db: &dyn HirDatabase, module: InternedModuleId<'_>) -> SymbolIndex {
+ let _p = tracing::info_span!("module_symbols").entered();
+
+ // We call this without attaching because this runs in parallel, so we need to attach here.
+ hir::attach_db(db, || {
+ SymbolIndex::new(SymbolCollector::new_module(db, module.id(db).into()))
+ })
+ }
+
+ module_symbols(db, InternedModuleId::new(db, hir::ModuleId::from(module)))
+ }
+}
+
impl fmt::Debug for SymbolIndex {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("SymbolIndex").field("n_symbols", &self.symbols.len()).finish()
@@ -309,7 +333,7 @@ impl SymbolIndex {
impl Query {
pub(crate) fn search<'sym, T>(
self,
- indices: &'sym [Arc<SymbolIndex>],
+ indices: &'sym [&SymbolIndex],
cb: impl FnMut(&'sym FileSymbol) -> ControlFlow<T>,
) -> Option<T> {
let _p = tracing::info_span!("symbol_index::Query::search").entered();
@@ -344,7 +368,7 @@ impl Query {
fn search_maps<'sym, T>(
&self,
- indices: &'sym [Arc<SymbolIndex>],
+ indices: &'sym [&SymbolIndex],
mut stream: fst::map::Union<'_>,
mut cb: impl FnMut(&'sym FileSymbol) -> ControlFlow<T>,
) -> Option<T> {
@@ -397,7 +421,7 @@ impl Query {
mod tests {
use expect_test::expect_file;
- use salsa::Durability;
+ use salsa::Setter;
use test_fixture::{WORKSPACE, WithFixture};
use super::*;
@@ -535,7 +559,7 @@ pub struct Foo;
let mut local_roots = FxHashSet::default();
local_roots.insert(WORKSPACE);
- db.set_local_roots_with_durability(Arc::new(local_roots), Durability::HIGH);
+ LocalRoots::get(&db).set_roots(&mut db).to(local_roots);
let mut query = Query::new("Foo".to_owned());
let mut symbols = world_symbols(&db, query.clone());
diff --git a/crates/ide-ssr/src/lib.rs b/crates/ide-ssr/src/lib.rs
index 43ad12c1f6..66ece4e4f0 100644
--- a/crates/ide-ssr/src/lib.rs
+++ b/crates/ide-ssr/src/lib.rs
@@ -80,7 +80,7 @@ pub use crate::{errors::SsrError, from_comment::ssr_from_comment, matching::Matc
use crate::{errors::bail, matching::MatchFailureReason};
use hir::{FileRange, Semantics};
-use ide_db::symbol_index::SymbolsDatabase;
+use ide_db::symbol_index::LocalRoots;
use ide_db::text_edit::TextEdit;
use ide_db::{EditionedFileId, FileId, FxHashMap, RootDatabase, base_db::SourceDatabase};
use resolving::ResolvedRule;
@@ -138,8 +138,8 @@ impl<'db> MatchFinder<'db> {
/// Constructs an instance using the start of the first file in `db` as the lookup context.
pub fn at_first_file(db: &'db ide_db::RootDatabase) -> Result<MatchFinder<'db>, SsrError> {
- if let Some(first_file_id) = db
- .local_roots()
+ if let Some(first_file_id) = LocalRoots::get(db)
+ .roots(db)
.iter()
.next()
.and_then(|root| db.source_root(*root).source_root(db).iter().next())
diff --git a/crates/ide-ssr/src/search.rs b/crates/ide-ssr/src/search.rs
index 72f857ceda..56484ae7a6 100644
--- a/crates/ide-ssr/src/search.rs
+++ b/crates/ide-ssr/src/search.rs
@@ -9,6 +9,7 @@ use ide_db::{
EditionedFileId, FileId, FxHashSet,
defs::Definition,
search::{SearchScope, UsageSearchResult},
+ symbol_index::LocalRoots,
};
use syntax::{AstNode, SyntaxKind, SyntaxNode, ast};
@@ -156,8 +157,7 @@ impl<'db> MatchFinder<'db> {
if self.restrict_ranges.is_empty() {
// Unrestricted search.
use ide_db::base_db::SourceDatabase;
- use ide_db::symbol_index::SymbolsDatabase;
- for &root in self.sema.db.local_roots().iter() {
+ for &root in LocalRoots::get(self.sema.db).roots(self.sema.db).iter() {
let sr = self.sema.db.source_root(root).source_root(self.sema.db);
for file_id in sr.iter() {
callback(file_id);
diff --git a/crates/ide-ssr/src/tests.rs b/crates/ide-ssr/src/tests.rs
index 1bb435f31f..852033599a 100644
--- a/crates/ide-ssr/src/tests.rs
+++ b/crates/ide-ssr/src/tests.rs
@@ -2,10 +2,10 @@ use expect_test::{Expect, expect};
use hir::{FilePosition, FileRange};
use ide_db::{
EditionedFileId, FxHashSet,
- base_db::{SourceDatabase, salsa::Durability},
+ base_db::{SourceDatabase, salsa::Setter},
+ symbol_index::LocalRoots,
};
use test_utils::RangeOrOffset;
-use triomphe::Arc;
use crate::{MatchFinder, SsrRule};
@@ -66,7 +66,6 @@ fn parser_undefined_placeholder_in_replacement() {
/// `code` may optionally contain a cursor marker `$0`. If it doesn't, then the position will be
/// the start of the file. If there's a second cursor marker, then we'll return a single range.
pub(crate) fn single_file(code: &str) -> (ide_db::RootDatabase, FilePosition, Vec<FileRange>) {
- use ide_db::symbol_index::SymbolsDatabase;
use test_fixture::{WORKSPACE, WithFixture};
let (mut db, file_id, range_or_offset) = if code.contains(test_utils::CURSOR_MARKER) {
ide_db::RootDatabase::with_range_or_offset(code)
@@ -88,7 +87,7 @@ pub(crate) fn single_file(code: &str) -> (ide_db::RootDatabase, FilePosition, Ve
}
let mut local_roots = FxHashSet::default();
local_roots.insert(WORKSPACE);
- db.set_local_roots_with_durability(Arc::new(local_roots), Durability::HIGH);
+ LocalRoots::get(&db).set_roots(&mut db).to(local_roots);
(db, position, selections)
}
diff --git a/crates/ide/src/ssr.rs b/crates/ide/src/ssr.rs
index 7df4499a0c..dc8f343207 100644
--- a/crates/ide/src/ssr.rs
+++ b/crates/ide/src/ssr.rs
@@ -59,11 +59,9 @@ mod tests {
use expect_test::expect;
use ide_assists::{Assist, AssistResolveStrategy};
use ide_db::{
- FileRange, FxHashSet, RootDatabase, base_db::salsa::Durability,
- symbol_index::SymbolsDatabase,
+ FileRange, FxHashSet, RootDatabase, base_db::salsa::Setter as _, symbol_index::LocalRoots,
};
use test_fixture::WithFixture;
- use triomphe::Arc;
use super::ssr_assists;
@@ -74,7 +72,7 @@ mod tests {
let (mut db, file_id, range_or_offset) = RootDatabase::with_range_or_offset(ra_fixture);
let mut local_roots = FxHashSet::default();
local_roots.insert(test_fixture::WORKSPACE);
- db.set_local_roots_with_durability(Arc::new(local_roots), Durability::HIGH);
+ LocalRoots::get(&db).set_roots(&mut db).to(local_roots);
ssr_assists(
&db,
&resolve,
diff --git a/crates/rust-analyzer/src/cli/ssr.rs b/crates/rust-analyzer/src/cli/ssr.rs
index e3e3a143de..975e81a4af 100644
--- a/crates/rust-analyzer/src/cli/ssr.rs
+++ b/crates/rust-analyzer/src/cli/ssr.rs
@@ -50,7 +50,6 @@ impl flags::Search {
/// for much else.
pub fn run(self) -> anyhow::Result<()> {
use ide_db::base_db::SourceDatabase;
- use ide_db::symbol_index::SymbolsDatabase;
let cargo_config =
CargoConfig { all_targets: true, set_test: true, ..CargoConfig::default() };
let load_cargo_config = LoadCargoConfig {
@@ -69,7 +68,7 @@ impl flags::Search {
match_finder.add_search_pattern(pattern)?;
}
if let Some(debug_snippet) = &self.debug {
- for &root in db.local_roots().iter() {
+ for &root in ide_db::symbol_index::LocalRoots::get(db).roots(db).iter() {
let sr = db.source_root(root).source_root(db);
for file_id in sr.iter() {
for debug_info in match_finder.debug_where_text_equal(