From 1c67944f99c06ef14aaffce5b7dc0258a995d125 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Sat, 27 Dec 2025 11:00:58 +0100 Subject: [PATCH] internal: Move library and local root inputs to base-db --- crates/base-db/src/change.rs | 16 +++++++++++-- crates/base-db/src/lib.rs | 18 ++++++++++++++- .../src/expr_store/tests/body/block.rs | 6 ++--- .../hir-def/src/macro_expansion_tests/mbe.rs | 16 ++++++------- crates/hir-def/src/nameres.rs | 22 ++++++++++++++++-- crates/hir-def/src/test_db.rs | 6 +++++ crates/hir-ty/src/test_db.rs | 6 +++++ crates/hir/src/semantics.rs | 2 +- crates/ide-db/src/apply_change.rs | 23 ++----------------- crates/ide-db/src/lib.rs | 6 ++--- crates/ide-db/src/symbol_index.rs | 20 ++-------------- crates/ide-ssr/src/lib.rs | 2 +- crates/ide-ssr/src/search.rs | 3 +-- crates/ide-ssr/src/tests.rs | 3 +-- crates/ide/src/ssr.rs | 4 +--- crates/rust-analyzer/src/cli/ssr.rs | 2 +- crates/stdx/src/lib.rs | 14 +++++++++++ 17 files changed, 101 insertions(+), 68 deletions(-) diff --git a/crates/base-db/src/change.rs b/crates/base-db/src/change.rs index da2fb27571..c728f3e5ca 100644 --- a/crates/base-db/src/change.rs +++ b/crates/base-db/src/change.rs @@ -3,11 +3,14 @@ use std::fmt; -use salsa::Durability; +use rustc_hash::FxHashSet; +use salsa::{Durability, Setter as _}; use triomphe::Arc; use vfs::FileId; -use crate::{CrateGraphBuilder, CratesIdMap, RootQueryDb, SourceRoot, SourceRootId}; +use crate::{ + CrateGraphBuilder, CratesIdMap, LibraryRoots, LocalRoots, RootQueryDb, SourceRoot, SourceRootId, +}; /// Encapsulate a bunch of raw `.set` calls on the database. #[derive(Default)] @@ -49,8 +52,15 @@ impl FileChange { pub fn apply(self, db: &mut dyn RootQueryDb) -> Option { let _p = tracing::info_span!("FileChange::apply").entered(); if let Some(roots) = self.roots { + let mut local_roots = FxHashSet::default(); + let mut library_roots = FxHashSet::default(); for (idx, root) in roots.into_iter().enumerate() { let root_id = SourceRootId(idx as u32); + if root.is_library { + library_roots.insert(root_id); + } else { + local_roots.insert(root_id); + } let durability = source_root_durability(&root); for file_id in root.iter() { db.set_file_source_root_with_durability(file_id, root_id, durability); @@ -58,6 +68,8 @@ impl FileChange { db.set_source_root_with_durability(root_id, Arc::new(root), durability); } + LocalRoots::get(db).set_roots(db).to(local_roots); + LibraryRoots::get(db).set_roots(db).to(library_roots); } for (file_id, text) in self.files_changed { diff --git a/crates/base-db/src/lib.rs b/crates/base-db/src/lib.rs index aa06cdefe6..24f6dd59a9 100644 --- a/crates/base-db/src/lib.rs +++ b/crates/base-db/src/lib.rs @@ -33,7 +33,7 @@ pub use crate::{ }; use dashmap::{DashMap, mapref::entry::Entry}; pub use query_group::{self}; -use rustc_hash::FxHasher; +use rustc_hash::{FxHashSet, FxHasher}; use salsa::{Durability, Setter}; pub use semver::{BuildMetadata, Prerelease, Version, VersionReq}; use syntax::{Parse, SyntaxError, ast}; @@ -203,6 +203,22 @@ impl Files { } } +/// 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, +} + +/// 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, +} + #[salsa_macros::input(debug)] pub struct FileText { #[returns(ref)] diff --git a/crates/hir-def/src/expr_store/tests/body/block.rs b/crates/hir-def/src/expr_store/tests/body/block.rs index 836a079e77..d457a4ca7a 100644 --- a/crates/hir-def/src/expr_store/tests/body/block.rs +++ b/crates/hir-def/src/expr_store/tests/body/block.rs @@ -190,13 +190,13 @@ fn f() { "#, expect![[r#" ModuleIdLt { - [salsa id]: Id(3003), + [salsa id]: Id(3803), krate: Crate( - Id(1c00), + Id(2400), ), block: Some( BlockId( - 3c01, + 4401, ), ), }"#]], diff --git a/crates/hir-def/src/macro_expansion_tests/mbe.rs b/crates/hir-def/src/macro_expansion_tests/mbe.rs index a12674f353..7b5d0103e6 100644 --- a/crates/hir-def/src/macro_expansion_tests/mbe.rs +++ b/crates/hir-def/src/macro_expansion_tests/mbe.rs @@ -35,9 +35,9 @@ macro_rules! f { }; } -struct#0:MacroRules[BE8F, 0]@58..64#15360# MyTraitMap2#0:MacroCall[BE8F, 0]@31..42#ROOT2024# {#0:MacroRules[BE8F, 0]@72..73#15360# - map#0:MacroRules[BE8F, 0]@86..89#15360#:#0:MacroRules[BE8F, 0]@89..90#15360# #0:MacroRules[BE8F, 0]@89..90#15360#::#0:MacroRules[BE8F, 0]@91..93#15360#std#0:MacroRules[BE8F, 0]@93..96#15360#::#0:MacroRules[BE8F, 0]@96..98#15360#collections#0:MacroRules[BE8F, 0]@98..109#15360#::#0:MacroRules[BE8F, 0]@109..111#15360#HashSet#0:MacroRules[BE8F, 0]@111..118#15360#<#0:MacroRules[BE8F, 0]@118..119#15360#(#0:MacroRules[BE8F, 0]@119..120#15360#)#0:MacroRules[BE8F, 0]@120..121#15360#>#0:MacroRules[BE8F, 0]@121..122#15360#,#0:MacroRules[BE8F, 0]@122..123#15360# -}#0:MacroRules[BE8F, 0]@132..133#15360# +struct#0:MacroRules[BE8F, 0]@58..64#17408# MyTraitMap2#0:MacroCall[BE8F, 0]@31..42#ROOT2024# {#0:MacroRules[BE8F, 0]@72..73#17408# + map#0:MacroRules[BE8F, 0]@86..89#17408#:#0:MacroRules[BE8F, 0]@89..90#17408# #0:MacroRules[BE8F, 0]@89..90#17408#::#0:MacroRules[BE8F, 0]@91..93#17408#std#0:MacroRules[BE8F, 0]@93..96#17408#::#0:MacroRules[BE8F, 0]@96..98#17408#collections#0:MacroRules[BE8F, 0]@98..109#17408#::#0:MacroRules[BE8F, 0]@109..111#17408#HashSet#0:MacroRules[BE8F, 0]@111..118#17408#<#0:MacroRules[BE8F, 0]@118..119#17408#(#0:MacroRules[BE8F, 0]@119..120#17408#)#0:MacroRules[BE8F, 0]@120..121#17408#>#0:MacroRules[BE8F, 0]@121..122#17408#,#0:MacroRules[BE8F, 0]@122..123#17408# +}#0:MacroRules[BE8F, 0]@132..133#17408# "#]], ); } @@ -197,7 +197,7 @@ macro_rules! mk_struct { #[macro_use] mod foo; -struct#1:MacroRules[DB0C, 0]@59..65#15360# Foo#0:MacroCall[DB0C, 0]@32..35#ROOT2024#(#1:MacroRules[DB0C, 0]@70..71#15360#u32#0:MacroCall[DB0C, 0]@41..44#ROOT2024#)#1:MacroRules[DB0C, 0]@74..75#15360#;#1:MacroRules[DB0C, 0]@75..76#15360# +struct#1:MacroRules[DB0C, 0]@59..65#17408# Foo#0:MacroCall[DB0C, 0]@32..35#ROOT2024#(#1:MacroRules[DB0C, 0]@70..71#17408#u32#0:MacroCall[DB0C, 0]@41..44#ROOT2024#)#1:MacroRules[DB0C, 0]@74..75#17408#;#1:MacroRules[DB0C, 0]@75..76#17408# "#]], ); } @@ -423,10 +423,10 @@ m! { foo, bar } macro_rules! m { ($($i:ident),*) => ( impl Bar { $(fn $i() {})* } ); } -impl#\15360# Bar#\15360# {#\15360# - fn#\15360# foo#\ROOT2024#(#\15360#)#\15360# {#\15360#}#\15360# - fn#\15360# bar#\ROOT2024#(#\15360#)#\15360# {#\15360#}#\15360# -}#\15360# +impl#\17408# Bar#\17408# {#\17408# + fn#\17408# foo#\ROOT2024#(#\17408#)#\17408# {#\17408#}#\17408# + fn#\17408# bar#\ROOT2024#(#\17408#)#\17408# {#\17408#}#\17408# +}#\17408# "#]], ); } diff --git a/crates/hir-def/src/nameres.rs b/crates/hir-def/src/nameres.rs index 59ca38c7c0..5f05cdb1e2 100644 --- a/crates/hir-def/src/nameres.rs +++ b/crates/hir-def/src/nameres.rs @@ -502,6 +502,7 @@ impl DefMap { } impl DefMap { + /// Returns all modules in the crate that are associated with the given file. pub fn modules_for_file<'a>( &'a self, db: &'a dyn DefDatabase, @@ -509,16 +510,33 @@ impl DefMap { ) -> impl Iterator + 'a { self.modules .iter() - .filter(move |(_id, data)| { + .filter(move |(_, data)| { data.origin.file_id().map(|file_id| file_id.file_id(db)) == Some(file_id) }) - .map(|(id, _data)| id) + .map(|(id, _)| id) } pub fn modules(&self) -> impl Iterator + '_ { self.modules.iter() } + /// Returns all inline modules (mod name { ... }) in the crate that are associated with the given macro expansion. + pub fn inline_modules_for_macro_file( + &self, + file_id: MacroCallId, + ) -> impl Iterator + '_ { + self.modules + .iter() + .filter(move |(_, data)| { + matches!( + data.origin, + ModuleOrigin::Inline { definition_tree_id, .. } + if definition_tree_id.file_id().macro_file() == Some(file_id) + ) + }) + .map(|(id, _)| id) + } + pub fn derive_helpers_in_scope( &self, id: AstId, diff --git a/crates/hir-def/src/test_db.rs b/crates/hir-def/src/test_db.rs index cdb49b2970..e8377fde49 100644 --- a/crates/hir-def/src/test_db.rs +++ b/crates/hir-def/src/test_db.rs @@ -49,6 +49,12 @@ impl Default for TestDB { this.set_expand_proc_attr_macros_with_durability(true, Durability::HIGH); // This needs to be here otherwise `CrateGraphBuilder` panics. this.set_all_crates(Arc::new(Box::new([]))); + _ = base_db::LibraryRoots::builder(Default::default()) + .durability(Durability::MEDIUM) + .new(&this); + _ = base_db::LocalRoots::builder(Default::default()) + .durability(Durability::MEDIUM) + .new(&this); CrateGraphBuilder::default().set_in_db(&mut this); this } diff --git a/crates/hir-ty/src/test_db.rs b/crates/hir-ty/src/test_db.rs index 7bd314cb8e..243456c85f 100644 --- a/crates/hir-ty/src/test_db.rs +++ b/crates/hir-ty/src/test_db.rs @@ -46,6 +46,12 @@ impl Default for TestDB { this.set_expand_proc_attr_macros_with_durability(true, Durability::HIGH); // This needs to be here otherwise `CrateGraphBuilder` panics. this.set_all_crates(Arc::new(Box::new([]))); + _ = base_db::LibraryRoots::builder(Default::default()) + .durability(Durability::MEDIUM) + .new(&this); + _ = base_db::LocalRoots::builder(Default::default()) + .durability(Durability::MEDIUM) + .new(&this); CrateGraphBuilder::default().set_in_db(&mut this); this } diff --git a/crates/hir/src/semantics.rs b/crates/hir/src/semantics.rs index 485011c38d..f4c42537de 100644 --- a/crates/hir/src/semantics.rs +++ b/crates/hir/src/semantics.rs @@ -836,7 +836,7 @@ impl<'db> SemanticsImpl<'db> { // FIXME: Type the return type /// Returns the range (pre-expansion) in the string literal corresponding to the resolution, /// absolute file range (post-expansion) - /// of the part in the format string, the corresponding string token and the resolution if it + /// of the part in the format string (post-expansion), the corresponding string token and the resolution if it /// exists. // FIXME: Remove this in favor of `check_for_format_args_template_with_file` pub fn check_for_format_args_template( diff --git a/crates/ide-db/src/apply_change.rs b/crates/ide-db/src/apply_change.rs index 6a85c6e548..9bbd12aaa9 100644 --- a/crates/ide-db/src/apply_change.rs +++ b/crates/ide-db/src/apply_change.rs @@ -1,14 +1,9 @@ //! Applies changes to the IDE state transactionally. -use base_db::SourceRootId; use profile::Bytes; -use rustc_hash::FxHashSet; -use salsa::{Database as _, Durability, Setter as _}; +use salsa::{Database as _, Durability}; -use crate::{ - ChangeWithProcMacros, RootDatabase, - symbol_index::{LibraryRoots, LocalRoots}, -}; +use crate::{ChangeWithProcMacros, RootDatabase}; impl RootDatabase { pub fn request_cancellation(&mut self) { @@ -20,20 +15,6 @@ impl RootDatabase { let _p = tracing::info_span!("RootDatabase::apply_change").entered(); self.request_cancellation(); tracing::trace!("apply_change {:?}", change); - if let Some(roots) = &change.source_change.roots { - let mut local_roots = FxHashSet::default(); - let mut library_roots = FxHashSet::default(); - for (idx, root) in roots.iter().enumerate() { - let root_id = SourceRootId(idx as u32); - if root.is_library { - library_roots.insert(root_id); - } else { - local_roots.insert(root_id); - } - } - 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/lib.rs b/crates/ide-db/src/lib.rs index 338c423254..413b58bf79 100644 --- a/crates/ide-db/src/lib.rs +++ b/crates/ide-db/src/lib.rs @@ -75,7 +75,7 @@ pub use rustc_hash::{FxHashMap, FxHashSet, FxHasher}; pub use ::line_index; /// `base_db` is normally also needed in places where `ide_db` is used, so this re-export is for convenience. -pub use base_db::{self, FxIndexMap, FxIndexSet}; +pub use base_db::{self, FxIndexMap, FxIndexSet, LibraryRoots, LocalRoots}; pub use span::{self, FileId}; pub type FilePosition = FilePositionWrapper; @@ -200,10 +200,10 @@ 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); - _ = crate::symbol_index::LibraryRoots::builder(Default::default()) + _ = base_db::LibraryRoots::builder(Default::default()) .durability(Durability::MEDIUM) .new(&db); - _ = crate::symbol_index::LocalRoots::builder(Default::default()) + _ = base_db::LocalRoots::builder(Default::default()) .durability(Durability::MEDIUM) .new(&db); db.set_expand_proc_attr_macros_with_durability(false, Durability::HIGH); diff --git a/crates/ide-db/src/symbol_index.rs b/crates/ide-db/src/symbol_index.rs index e15d0b33bb..eb0529d6b5 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, SourceRootId}; +use base_db::{LibraryRoots, LocalRoots, RootQueryDb, SourceRootId}; use fst::{Automaton, Streamer, raw::IndexedValue}; use hir::{ Crate, Module, @@ -36,7 +36,6 @@ use hir::{ symbols::{FileSymbol, SymbolCollector}, }; use rayon::prelude::*; -use rustc_hash::FxHashSet; use salsa::Update; use crate::RootDatabase; @@ -102,22 +101,6 @@ impl Query { } } -/// 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, -} - -/// 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, -} - /// 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(); @@ -443,6 +426,7 @@ impl Query { mod tests { use expect_test::expect_file; + use rustc_hash::FxHashSet; use salsa::Setter; use test_fixture::{WORKSPACE, WithFixture}; diff --git a/crates/ide-ssr/src/lib.rs b/crates/ide-ssr/src/lib.rs index 958a26324f..a614d71c1f 100644 --- a/crates/ide-ssr/src/lib.rs +++ b/crates/ide-ssr/src/lib.rs @@ -85,7 +85,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::LocalRoots; +use ide_db::LocalRoots; use ide_db::text_edit::TextEdit; use ide_db::{EditionedFileId, FileId, FxHashMap, RootDatabase, base_db::SourceDatabase}; use resolving::ResolvedRule; diff --git a/crates/ide-ssr/src/search.rs b/crates/ide-ssr/src/search.rs index 5f54c66d3c..51e4951cf6 100644 --- a/crates/ide-ssr/src/search.rs +++ b/crates/ide-ssr/src/search.rs @@ -6,10 +6,9 @@ use crate::{ }; use hir::FileRange; use ide_db::{ - FileId, FxHashSet, + FileId, FxHashSet, LocalRoots, defs::Definition, search::{SearchScope, UsageSearchResult}, - symbol_index::LocalRoots, }; use syntax::{AstNode, SyntaxKind, SyntaxNode, ast}; diff --git a/crates/ide-ssr/src/tests.rs b/crates/ide-ssr/src/tests.rs index 852033599a..b3d09cac42 100644 --- a/crates/ide-ssr/src/tests.rs +++ b/crates/ide-ssr/src/tests.rs @@ -1,9 +1,8 @@ use expect_test::{Expect, expect}; use hir::{FilePosition, FileRange}; use ide_db::{ - EditionedFileId, FxHashSet, + EditionedFileId, FxHashSet, LocalRoots, base_db::{SourceDatabase, salsa::Setter}, - symbol_index::LocalRoots, }; use test_utils::RangeOrOffset; diff --git a/crates/ide/src/ssr.rs b/crates/ide/src/ssr.rs index dc8f343207..4dfb5fe816 100644 --- a/crates/ide/src/ssr.rs +++ b/crates/ide/src/ssr.rs @@ -58,9 +58,7 @@ pub(crate) fn ssr_assists( mod tests { use expect_test::expect; use ide_assists::{Assist, AssistResolveStrategy}; - use ide_db::{ - FileRange, FxHashSet, RootDatabase, base_db::salsa::Setter as _, symbol_index::LocalRoots, - }; + use ide_db::{FileRange, FxHashSet, LocalRoots, RootDatabase, base_db::salsa::Setter as _}; use test_fixture::WithFixture; use super::ssr_assists; diff --git a/crates/rust-analyzer/src/cli/ssr.rs b/crates/rust-analyzer/src/cli/ssr.rs index 529cf12082..3918683145 100644 --- a/crates/rust-analyzer/src/cli/ssr.rs +++ b/crates/rust-analyzer/src/cli/ssr.rs @@ -68,7 +68,7 @@ impl flags::Search { match_finder.add_search_pattern(pattern)?; } if let Some(debug_snippet) = &self.debug { - for &root in ide_db::symbol_index::LocalRoots::get(db).roots(db).iter() { + for &root in ide_db::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( diff --git a/crates/stdx/src/lib.rs b/crates/stdx/src/lib.rs index 5fa0074163..7ab26b1890 100644 --- a/crates/stdx/src/lib.rs +++ b/crates/stdx/src/lib.rs @@ -76,6 +76,20 @@ impl TupleExt for (T, U, V) { } } +impl TupleExt for &T +where + T: TupleExt + Copy, +{ + type Head = T::Head; + type Tail = T::Tail; + fn head(self) -> Self::Head { + (*self).head() + } + fn tail(self) -> Self::Tail { + (*self).tail() + } +} + pub fn to_lower_snake_case(s: &str) -> String { to_snake_case(s, char::to_lowercase) }