Merge pull request #20997 from Veykril/push-zsuorxrkpupr

perf: Only populate public items in dependency symbol index
This commit is contained in:
Lukas Wirth 2025-11-09 12:38:57 +00:00 committed by Laurențiu Nicola
parent 574567baf9
commit 18851eb06b
2 changed files with 41 additions and 12 deletions

View file

@ -66,22 +66,28 @@ pub struct SymbolCollector<'a> {
symbols: FxIndexSet<FileSymbol>, symbols: FxIndexSet<FileSymbol>,
work: Vec<SymbolCollectorWork>, work: Vec<SymbolCollectorWork>,
current_container_name: Option<Symbol>, current_container_name: Option<Symbol>,
collect_pub_only: bool,
} }
/// Given a [`ModuleId`] and a [`HirDatabase`], use the DefMap for the module's crate to collect /// Given a [`ModuleId`] and a [`HirDatabase`], use the DefMap for the module's crate to collect
/// all symbols that should be indexed for the given module. /// all symbols that should be indexed for the given module.
impl<'a> SymbolCollector<'a> { impl<'a> SymbolCollector<'a> {
pub fn new(db: &'a dyn HirDatabase) -> Self { pub fn new(db: &'a dyn HirDatabase, collect_pub_only: bool) -> Self {
SymbolCollector { SymbolCollector {
db, db,
symbols: Default::default(), symbols: Default::default(),
work: Default::default(), work: Default::default(),
current_container_name: None, current_container_name: None,
collect_pub_only,
} }
} }
pub fn new_module(db: &dyn HirDatabase, module: Module) -> Box<[FileSymbol]> { pub fn new_module(
let mut symbol_collector = SymbolCollector::new(db); db: &dyn HirDatabase,
module: Module,
collect_pub_only: bool,
) -> Box<[FileSymbol]> {
let mut symbol_collector = SymbolCollector::new(db, collect_pub_only);
symbol_collector.collect(module); symbol_collector.collect(module);
symbol_collector.finish() symbol_collector.finish()
} }
@ -113,7 +119,11 @@ impl<'a> SymbolCollector<'a> {
} }
fn collect_from_module(&mut self, module_id: ModuleId) { fn collect_from_module(&mut self, module_id: ModuleId) {
let push_decl = |this: &mut Self, def, name| { let collect_pub_only = self.collect_pub_only;
let push_decl = |this: &mut Self, def: ModuleDefId, name, vis| {
if collect_pub_only && vis != Visibility::Public {
return;
}
match def { match def {
ModuleDefId::ModuleId(id) => this.push_module(id, name), ModuleDefId::ModuleId(id) => this.push_module(id, name),
ModuleDefId::FunctionId(id) => { ModuleDefId::FunctionId(id) => {
@ -175,6 +185,9 @@ impl<'a> SymbolCollector<'a> {
}; };
let mut push_import = |this: &mut Self, i: ImportId, name: &Name, def: ModuleDefId, vis| { let mut push_import = |this: &mut Self, i: ImportId, name: &Name, def: ModuleDefId, vis| {
if collect_pub_only && vis != Visibility::Public {
return;
}
let source = import_child_source_cache let source = import_child_source_cache
.entry(i.use_) .entry(i.use_)
.or_insert_with(|| i.use_.child_source(this.db)); .or_insert_with(|| i.use_.child_source(this.db));
@ -209,6 +222,9 @@ impl<'a> SymbolCollector<'a> {
let push_extern_crate = let push_extern_crate =
|this: &mut Self, i: ExternCrateId, name: &Name, def: ModuleDefId, vis| { |this: &mut Self, i: ExternCrateId, name: &Name, def: ModuleDefId, vis| {
if collect_pub_only && vis != Visibility::Public {
return;
}
let loc = i.lookup(this.db); let loc = i.lookup(this.db);
let source = loc.source(this.db); let source = loc.source(this.db);
let rename = source.value.rename().and_then(|rename| rename.name()); let rename = source.value.rename().and_then(|rename| rename.name());
@ -258,7 +274,7 @@ impl<'a> SymbolCollector<'a> {
continue; continue;
} }
// self is a declaration // self is a declaration
push_decl(self, def, name) push_decl(self, def, name, vis)
} }
for (name, Item { def, vis, import }) in scope.macros() { for (name, Item { def, vis, import }) in scope.macros() {
@ -271,7 +287,7 @@ impl<'a> SymbolCollector<'a> {
continue; continue;
} }
// self is a declaration // self is a declaration
push_decl(self, def.into(), name) push_decl(self, ModuleDefId::MacroId(def), name, vis)
} }
for (name, Item { def, vis, import }) in scope.values() { for (name, Item { def, vis, import }) in scope.values() {
@ -283,7 +299,7 @@ impl<'a> SymbolCollector<'a> {
continue; continue;
} }
// self is a declaration // self is a declaration
push_decl(self, def, name) push_decl(self, def, name, vis)
} }
for const_id in scope.unnamed_consts() { for const_id in scope.unnamed_consts() {
@ -304,6 +320,9 @@ impl<'a> SymbolCollector<'a> {
} }
fn collect_from_body(&mut self, body_id: impl Into<DefWithBodyId>, name: Option<Name>) { fn collect_from_body(&mut self, body_id: impl Into<DefWithBodyId>, name: Option<Name>) {
if self.collect_pub_only {
return;
}
let body_id = body_id.into(); let body_id = body_id.into();
let body = self.db.body(body_id); let body = self.db.body(body_id);
@ -330,6 +349,11 @@ impl<'a> SymbolCollector<'a> {
); );
self.with_container_name(impl_name.as_deref().map(Symbol::intern), |s| { self.with_container_name(impl_name.as_deref().map(Symbol::intern), |s| {
for &(ref name, assoc_item_id) in &impl_id.impl_items(self.db).items { for &(ref name, assoc_item_id) in &impl_id.impl_items(self.db).items {
if s.collect_pub_only && s.db.assoc_visibility(assoc_item_id) != Visibility::Public
{
continue;
}
s.push_assoc_item(assoc_item_id, name, None) s.push_assoc_item(assoc_item_id, name, None)
} }
}) })

View file

@ -206,13 +206,13 @@ impl SymbolIndex {
// We call this without attaching because this runs in parallel, so we need to attach here. // We call this without attaching because this runs in parallel, so we need to attach here.
hir::attach_db(db, || { hir::attach_db(db, || {
let mut symbol_collector = SymbolCollector::new(db); let mut symbol_collector = SymbolCollector::new(db, true);
db.source_root_crates(source_root_id.id(db)) db.source_root_crates(source_root_id.id(db))
.iter() .iter()
.flat_map(|&krate| Crate::from(krate).modules(db)) .flat_map(|&krate| Crate::from(krate).modules(db))
// we specifically avoid calling other SymbolsDatabase queries here, even though they do the same thing, // 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 // as the index for a library is not going to really ever change, and we do not want to store
// the module or crate indices for those in salsa unless we need to. // the module or crate indices for those in salsa unless we need to.
.for_each(|module| symbol_collector.collect(module)); .for_each(|module| symbol_collector.collect(module));
@ -237,7 +237,12 @@ impl SymbolIndex {
// We call this without attaching because this runs in parallel, so we need to attach here. // We call this without attaching because this runs in parallel, so we need to attach here.
hir::attach_db(db, || { hir::attach_db(db, || {
SymbolIndex::new(SymbolCollector::new_module(db, module.id(db).into())) let module: Module = module.id(db).into();
SymbolIndex::new(SymbolCollector::new_module(
db,
module,
!module.krate().origin(db).is_local(),
))
}) })
} }
@ -508,7 +513,7 @@ pub(self) use crate::Trait as IsThisJustATrait;
.modules(&db) .modules(&db)
.into_iter() .into_iter()
.map(|module_id| { .map(|module_id| {
let mut symbols = SymbolCollector::new_module(&db, module_id); let mut symbols = SymbolCollector::new_module(&db, module_id, false);
symbols.sort_by_key(|it| it.name.as_str().to_owned()); symbols.sort_by_key(|it| it.name.as_str().to_owned());
(module_id, symbols) (module_id, symbols)
}) })
@ -535,7 +540,7 @@ struct Duplicate;
.modules(&db) .modules(&db)
.into_iter() .into_iter()
.map(|module_id| { .map(|module_id| {
let mut symbols = SymbolCollector::new_module(&db, module_id); let mut symbols = SymbolCollector::new_module(&db, module_id, false);
symbols.sort_by_key(|it| it.name.as_str().to_owned()); symbols.sort_by_key(|it| it.name.as_str().to_owned());
(module_id, symbols) (module_id, symbols)
}) })