Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions crates/hir/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ pub mod term_search;

mod display;

#[doc(hidden)]
pub use hir_def::ModuleId;

use std::{
fmt,
mem::discriminant,
Expand All @@ -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,
Expand Down
12 changes: 7 additions & 5 deletions crates/ide-db/src/apply_change.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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);
}
Expand Down
4 changes: 2 additions & 2 deletions crates/ide-db/src/items_locator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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),
Expand Down
10 changes: 7 additions & 3 deletions crates/ide-db/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand Down
7 changes: 4 additions & 3 deletions crates/ide-db/src/prime_caches.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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
Expand Down
154 changes: 89 additions & 65 deletions crates/ide-db/src/symbol_index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -37,7 +37,6 @@ use hir::{
};
use rayon::prelude::*;
use rustc_hash::FxHashSet;
use triomphe::Arc;

use crate::RootDatabase;

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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()
};

Expand All @@ -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()
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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> {
Expand Down Expand Up @@ -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::*;
Expand Down Expand Up @@ -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());
Expand Down
6 changes: 3 additions & 3 deletions crates/ide-ssr/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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())
Expand Down
4 changes: 2 additions & 2 deletions crates/ide-ssr/src/search.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use ide_db::{
EditionedFileId, FileId, FxHashSet,
defs::Definition,
search::{SearchScope, UsageSearchResult},
symbol_index::LocalRoots,
};
use syntax::{AstNode, SyntaxKind, SyntaxNode, ast};

Expand Down Expand Up @@ -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);
Expand Down
Loading