From a1a9514f6fa4416312f41fc005fc6ae3c615c64d Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Sun, 30 Nov 2025 13:56:00 +0100 Subject: [PATCH] Turn `BlockLoc` into a tracked struct --- .../rust-analyzer/crates/hir-def/src/db.rs | 15 ++--- .../crates/hir-def/src/expr_store/lower.rs | 4 +- .../src/expr_store/tests/body/block.rs | 52 ++++++++++++++- .../crates/hir-def/src/find_path.rs | 66 +++++++++---------- .../crates/hir-def/src/import_map.rs | 6 +- .../crates/hir-def/src/item_tree.rs | 8 +-- .../rust-analyzer/crates/hir-def/src/lib.rs | 61 +++++++++++------ .../crates/hir-def/src/nameres.rs | 32 +++++---- .../crates/hir-def/src/resolver.rs | 4 +- .../crates/hir-def/src/visibility.rs | 30 +++++---- .../rust-analyzer/crates/hir-ty/src/infer.rs | 23 +++---- .../crates/hir-ty/src/method_resolution.rs | 49 +++++++------- src/tools/rust-analyzer/crates/hir/src/lib.rs | 8 +-- .../hir/src/semantics/child_by_source.rs | 2 +- 14 files changed, 214 insertions(+), 146 deletions(-) diff --git a/src/tools/rust-analyzer/crates/hir-def/src/db.rs b/src/tools/rust-analyzer/crates/hir-def/src/db.rs index ccd4bc9be84a..98df8d0ff445 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/db.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/db.rs @@ -8,12 +8,12 @@ use la_arena::ArenaMap; use triomphe::Arc; use crate::{ - AssocItemId, AttrDefId, BlockId, BlockLoc, ConstId, ConstLoc, DefWithBodyId, EnumId, EnumLoc, - EnumVariantId, EnumVariantLoc, ExternBlockId, ExternBlockLoc, ExternCrateId, ExternCrateLoc, - FunctionId, FunctionLoc, GenericDefId, ImplId, ImplLoc, LocalFieldId, Macro2Id, Macro2Loc, - MacroExpander, MacroId, MacroRulesId, MacroRulesLoc, MacroRulesLocFlags, ProcMacroId, - ProcMacroLoc, StaticId, StaticLoc, StructId, StructLoc, TraitId, TraitLoc, TypeAliasId, - TypeAliasLoc, UnionId, UnionLoc, UseId, UseLoc, VariantId, + AssocItemId, AttrDefId, ConstId, ConstLoc, DefWithBodyId, EnumId, EnumLoc, EnumVariantId, + EnumVariantLoc, ExternBlockId, ExternBlockLoc, ExternCrateId, ExternCrateLoc, FunctionId, + FunctionLoc, GenericDefId, ImplId, ImplLoc, LocalFieldId, Macro2Id, Macro2Loc, MacroExpander, + MacroId, MacroRulesId, MacroRulesLoc, MacroRulesLocFlags, ProcMacroId, ProcMacroLoc, StaticId, + StaticLoc, StructId, StructLoc, TraitId, TraitLoc, TypeAliasId, TypeAliasLoc, UnionId, + UnionLoc, UseId, UseLoc, VariantId, attrs::AttrFlags, expr_store::{ Body, BodySourceMap, ExpressionStore, ExpressionStoreSourceMap, scope::ExprScopes, @@ -82,9 +82,6 @@ pub trait InternDatabase: RootQueryDb { #[salsa::interned] fn intern_macro_rules(&self, loc: MacroRulesLoc) -> MacroRulesId; // endregion: items - - #[salsa::interned] - fn intern_block(&self, loc: BlockLoc) -> BlockId; } #[query_group::query_group] diff --git a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower.rs b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower.rs index df4cff0b8a17..f374dd2cc9ef 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/lower.rs @@ -31,7 +31,7 @@ use triomphe::Arc; use tt::TextRange; use crate::{ - AdtId, BlockId, BlockLoc, DefWithBodyId, FunctionId, GenericDefId, ImplId, MacroId, + AdtId, BlockId, BlockIdLt, DefWithBodyId, FunctionId, GenericDefId, ImplId, MacroId, ModuleDefId, ModuleId, TraitId, TypeAliasId, UnresolvedMacro, attrs::AttrFlags, builtin_type::BuiltinUint, @@ -2114,7 +2114,7 @@ impl<'db> ExprCollector<'db> { ) -> ExprId { let block_id = self.expander.ast_id_map().ast_id_for_block(&block).map(|file_local_id| { let ast_id = self.expander.in_file(file_local_id); - self.db.intern_block(BlockLoc { ast_id, module: self.module }) + unsafe { BlockIdLt::new(self.db, ast_id, self.module).to_static() } }); let (module, def_map) = diff --git a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/tests/body/block.rs b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/tests/body/block.rs index 836a079e777f..2d60f44092c5 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/expr_store/tests/body/block.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/expr_store/tests/body/block.rs @@ -195,9 +195,55 @@ fn f() { Id(1c00), ), block: Some( - BlockId( - 3c01, - ), + BlockIdLt { + [salsa id]: Id(3c01), + ast_id: InFileWrapper { + file_id: FileId( + EditionedFileIdData { + editioned_file_id: EditionedFileId( + 0, + Edition2024, + ), + krate: Crate( + Id(1c00), + ), + }, + ), + value: FileAstId::(ErasedFileAstId { kind: BlockExpr, index: 0, hash: F9BF }), + }, + module: ModuleIdLt { + [salsa id]: Id(3002), + krate: Crate( + Id(1c00), + ), + block: Some( + BlockIdLt { + [salsa id]: Id(3c00), + ast_id: InFileWrapper { + file_id: FileId( + EditionedFileIdData { + editioned_file_id: EditionedFileId( + 0, + Edition2024, + ), + krate: Crate( + Id(1c00), + ), + }, + ), + value: FileAstId::(ErasedFileAstId { kind: BlockExpr, index: 0, hash: C181 }), + }, + module: ModuleIdLt { + [salsa id]: Id(3000), + krate: Crate( + Id(1c00), + ), + block: None, + }, + }, + ), + }, + }, ), }"#]], ); diff --git a/src/tools/rust-analyzer/crates/hir-def/src/find_path.rs b/src/tools/rust-analyzer/crates/hir-def/src/find_path.rs index 5d1cac8e93c4..cc0594f00d61 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/find_path.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/find_path.rs @@ -12,7 +12,7 @@ use intern::sym; use rustc_hash::FxHashSet; use crate::{ - FindPathConfig, ModuleDefId, ModuleId, + FindPathConfig, ModuleDefId, ModuleIdLt, db::DefDatabase, item_scope::ItemInNs, nameres::DefMap, @@ -24,7 +24,7 @@ use crate::{ pub fn find_path( db: &dyn DefDatabase, item: ItemInNs, - from: ModuleId, + from: ModuleIdLt<'_>, mut prefix_kind: PrefixKind, ignore_local_imports: bool, mut cfg: FindPathConfig, @@ -102,14 +102,14 @@ struct FindPathCtx<'db> { cfg: FindPathConfig, ignore_local_imports: bool, is_std_item: bool, - from: ModuleId, + from: ModuleIdLt<'db>, from_crate: Crate, - crate_root: ModuleId, + crate_root: ModuleIdLt<'db>, from_def_map: &'db DefMap, fuel: Cell, } -/// Attempts to find a path to refer to the given `item` visible from the `from` ModuleId +/// Attempts to find a path to refer to the given `item` visible from the `from` ModuleIdLt<'_> fn find_path_inner(ctx: &FindPathCtx<'_>, item: ItemInNs, max_len: usize) -> Option { // - if the item is a module, jump straight to module search if !ctx.is_std_item @@ -157,10 +157,10 @@ fn find_path_inner(ctx: &FindPathCtx<'_>, item: ItemInNs, max_len: usize) -> Opt } #[tracing::instrument(skip_all)] -fn find_path_for_module( - ctx: &FindPathCtx<'_>, - visited_modules: &mut FxHashSet<(ItemInNs, ModuleId)>, - module_id: ModuleId, +fn find_path_for_module<'db>( + ctx: &'db FindPathCtx<'db>, + visited_modules: &mut FxHashSet<(ItemInNs, ModuleIdLt<'db>)>, + module_id: ModuleIdLt<'db>, maybe_extern: bool, max_len: usize, ) -> Option { @@ -217,7 +217,7 @@ fn find_path_for_module( ctx.db, ctx.from_def_map, ctx.from, - ItemInNs::Types(module_id.into()), + ItemInNs::Types(unsafe { module_id.to_static() }.into()), ctx.ignore_local_imports, ); if let Some(scope_name) = scope_name { @@ -244,7 +244,7 @@ fn find_path_for_module( } // - if the module is in the prelude, return it by that path - let item = ItemInNs::Types(module_id.into()); + let item = ItemInNs::Types(unsafe { module_id.to_static() }.into()); if let Some(choice) = find_in_prelude(ctx.db, ctx.from_def_map, item, ctx.from) { return Some(choice); } @@ -257,10 +257,10 @@ fn find_path_for_module( best_choice } -fn find_in_scope( - db: &dyn DefDatabase, +fn find_in_scope<'db>( + db: &'db dyn DefDatabase, def_map: &DefMap, - from: ModuleId, + from: ModuleIdLt<'db>, item: ItemInNs, ignore_local_imports: bool, ) -> Option { @@ -278,7 +278,7 @@ fn find_in_prelude( db: &dyn DefDatabase, local_def_map: &DefMap, item: ItemInNs, - from: ModuleId, + from: ModuleIdLt<'_>, ) -> Option { let (prelude_module, _) = local_def_map.prelude()?; let prelude_def_map = prelude_module.def_map(db); @@ -310,8 +310,8 @@ fn find_in_prelude( fn is_kw_kind_relative_to_from( db: &dyn DefDatabase, def_map: &DefMap, - item: ModuleId, - from: ModuleId, + item: ModuleIdLt<'_>, + from: ModuleIdLt<'_>, ) -> Option { if item.krate(db) != from.krate(db) || item.block(db).is_some() || from.block(db).is_some() { return None; @@ -332,9 +332,9 @@ fn is_kw_kind_relative_to_from( } #[tracing::instrument(skip_all)] -fn calculate_best_path( - ctx: &FindPathCtx<'_>, - visited_modules: &mut FxHashSet<(ItemInNs, ModuleId)>, +fn calculate_best_path<'db>( + ctx: &'db FindPathCtx<'db>, + visited_modules: &mut FxHashSet<(ItemInNs, ModuleIdLt<'db>)>, item: ItemInNs, max_len: usize, best_choice: &mut Option, @@ -372,9 +372,9 @@ fn calculate_best_path( } } -fn find_in_sysroot( - ctx: &FindPathCtx<'_>, - visited_modules: &mut FxHashSet<(ItemInNs, ModuleId)>, +fn find_in_sysroot<'db>( + ctx: &'db FindPathCtx<'db>, + visited_modules: &mut FxHashSet<(ItemInNs, ModuleIdLt<'db>)>, item: ItemInNs, max_len: usize, best_choice: &mut Option, @@ -418,9 +418,9 @@ fn find_in_sysroot( }); } -fn find_in_dep( - ctx: &FindPathCtx<'_>, - visited_modules: &mut FxHashSet<(ItemInNs, ModuleId)>, +fn find_in_dep<'db>( + ctx: &'db FindPathCtx<'db>, + visited_modules: &mut FxHashSet<(ItemInNs, ModuleIdLt<'db>)>, item: ItemInNs, max_len: usize, best_choice: &mut Option, @@ -461,9 +461,9 @@ fn find_in_dep( } } -fn calculate_best_path_local( - ctx: &FindPathCtx<'_>, - visited_modules: &mut FxHashSet<(ItemInNs, ModuleId)>, +fn calculate_best_path_local<'db>( + ctx: &'db FindPathCtx<'db>, + visited_modules: &mut FxHashSet<(ItemInNs, ModuleIdLt<'db>)>, item: ItemInNs, max_len: usize, best_choice: &mut Option, @@ -558,11 +558,11 @@ fn path_kind_len(kind: PathKind) -> usize { } /// Finds locations in `from.krate` from which `item` can be imported by `from`. -fn find_local_import_locations( - ctx: &FindPathCtx<'_>, +fn find_local_import_locations<'db>( + ctx: &'db FindPathCtx<'db>, item: ItemInNs, - visited_modules: &mut FxHashSet<(ItemInNs, ModuleId)>, - mut cb: impl FnMut(&mut FxHashSet<(ItemInNs, ModuleId)>, &Name, ModuleId), + visited_modules: &mut FxHashSet<(ItemInNs, ModuleIdLt<'db>)>, + mut cb: impl FnMut(&mut FxHashSet<(ItemInNs, ModuleIdLt<'db>)>, &Name, ModuleIdLt<'db>), ) { let _p = tracing::info_span!("find_local_import_locations").entered(); let db = ctx.db; diff --git a/src/tools/rust-analyzer/crates/hir-def/src/import_map.rs b/src/tools/rust-analyzer/crates/hir-def/src/import_map.rs index 6c5d226cac1b..433aead77adb 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/import_map.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/import_map.rs @@ -496,7 +496,7 @@ mod tests { use expect_test::{Expect, expect}; use test_fixture::WithFixture; - use crate::{ItemContainerId, Lookup, nameres::assoc::TraitItems, test_db::TestDB}; + use crate::{ItemContainerId, Lookup, ModuleIdLt, nameres::assoc::TraitItems, test_db::TestDB}; use super::*; @@ -628,8 +628,8 @@ mod tests { expect.assert_eq(&actual) } - fn render_path(db: &dyn DefDatabase, info: &ImportInfo) -> String { - let mut module = info.container; + fn render_path<'db>(db: &'db dyn DefDatabase, info: &ImportInfo) -> String { + let mut module: ModuleIdLt<'db> = info.container; let mut segments = vec![&info.name]; let def_map = module.def_map(db); diff --git a/src/tools/rust-analyzer/crates/hir-def/src/item_tree.rs b/src/tools/rust-analyzer/crates/hir-def/src/item_tree.rs index 2a104fff2b92..1228d1999bcb 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/item_tree.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/item_tree.rs @@ -58,7 +58,7 @@ use syntax::{SyntaxKind, ast, match_ast}; use thin_vec::ThinVec; use triomphe::Arc; -use crate::{BlockId, Lookup, db::DefDatabase}; +use crate::{BlockId, db::DefDatabase}; pub(crate) use crate::item_tree::{ attrs::*, @@ -150,10 +150,10 @@ pub(crate) fn block_item_tree_query(db: &dyn DefDatabase, block: BlockId) -> Arc let _p = tracing::info_span!("block_item_tree_query", ?block).entered(); static EMPTY: OnceLock> = OnceLock::new(); - let loc = block.lookup(db); - let block = loc.ast_id.to_node(db); + let ast_id = block.ast_id(db); + let block = ast_id.to_node(db); - let ctx = lower::Ctx::new(db, loc.ast_id.file_id); + let ctx = lower::Ctx::new(db, ast_id.file_id); let mut item_tree = ctx.lower_block(&block); let ItemTree { top_level, top_attrs, attrs, vis, big_data, small_data } = &item_tree; if small_data.is_empty() diff --git a/src/tools/rust-analyzer/crates/hir-def/src/lib.rs b/src/tools/rust-analyzer/crates/hir-def/src/lib.rs index 97af8ad93def..e58cb7bad705 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/lib.rs @@ -420,13 +420,31 @@ pub struct ProcMacroLoc { impl_intern!(ProcMacroId, ProcMacroLoc, intern_proc_macro, lookup_intern_proc_macro); impl_loc!(ProcMacroLoc, id: Fn, container: ModuleId); -#[derive(Debug, Hash, PartialEq, Eq, Clone)] -pub struct BlockLoc { +#[salsa_macros::tracked(debug)] +#[derive(PartialOrd, Ord)] +pub struct BlockIdLt<'db> { pub ast_id: AstId, /// The containing module. - pub module: ModuleId, + pub module: ModuleIdLt<'db>, +} +pub type BlockId = BlockIdLt<'static>; + +impl BlockIdLt<'_> { + /// # Safety + /// + /// The caller must ensure that the `ModuleId` is not leaked outside of query computations. + pub unsafe fn to_static(self) -> BlockId { + unsafe { std::mem::transmute(self) } + } +} +impl BlockId { + /// # Safety + /// + /// The caller must ensure that the `BlockId` comes from the given database. + pub unsafe fn to_db<'db>(self, _db: &'db dyn DefDatabase) -> BlockIdLt<'db> { + unsafe { std::mem::transmute(self) } + } } -impl_intern!(BlockId, BlockLoc, intern_block, lookup_intern_block); #[salsa_macros::tracked(debug)] #[derive(PartialOrd, Ord)] @@ -436,34 +454,26 @@ pub struct ModuleIdLt<'db> { /// If this `ModuleId` was derived from a `DefMap` for a block expression, this stores the /// `BlockId` of that block expression. If `None`, this module is part of the crate-level /// `DefMap` of `krate`. - pub block: Option, + pub block: Option>, } pub type ModuleId = ModuleIdLt<'static>; -impl ModuleIdLt<'_> { +impl<'db> ModuleIdLt<'db> { /// # Safety /// /// The caller must ensure that the `ModuleId` is not leaked outside of query computations. pub unsafe fn to_static(self) -> ModuleId { unsafe { std::mem::transmute(self) } } -} -impl ModuleId { - /// # Safety - /// - /// The caller must ensure that the `ModuleId` comes from the given database. - pub unsafe fn to_db<'db>(self, _db: &'db dyn DefDatabase) -> ModuleIdLt<'db> { - unsafe { std::mem::transmute(self) } - } - pub fn def_map(self, db: &dyn DefDatabase) -> &DefMap { + pub fn def_map(self, db: &'db dyn DefDatabase) -> &'db DefMap { match self.block(db) { Some(block) => block_def_map(db, block), None => crate_def_map(db, self.krate(db)), } } - pub(crate) fn local_def_map(self, db: &dyn DefDatabase) -> (&DefMap, &LocalDefMap) { + pub(crate) fn local_def_map(self, db: &'db dyn DefDatabase) -> (&'db DefMap, &'db LocalDefMap) { match self.block(db) { Some(block) => (block_def_map(db, block), self.only_local_def_map(db)), None => { @@ -473,15 +483,15 @@ impl ModuleId { } } - pub(crate) fn only_local_def_map(self, db: &dyn DefDatabase) -> &LocalDefMap { + pub(crate) fn only_local_def_map(self, db: &'db dyn DefDatabase) -> &'db LocalDefMap { crate_local_def_map(db, self.krate(db)).local(db) } - pub fn crate_def_map(self, db: &dyn DefDatabase) -> &DefMap { + pub fn crate_def_map(self, db: &'db dyn DefDatabase) -> &'db DefMap { crate_def_map(db, self.krate(db)) } - pub fn name(self, db: &dyn DefDatabase) -> Option { + pub fn name(self, db: &'db dyn DefDatabase) -> Option { let def_map = self.def_map(db); let parent = def_map[self].parent?; def_map[parent].children.iter().find_map(|(name, module_id)| { @@ -491,15 +501,24 @@ impl ModuleId { /// Returns the module containing `self`, either the parent `mod`, or the module (or block) containing /// the block, if `self` corresponds to a block expression. - pub fn containing_module(self, db: &dyn DefDatabase) -> Option { + pub fn containing_module(self, db: &'db dyn DefDatabase) -> Option> { self.def_map(db).containing_module(self) } - pub fn is_block_module(self, db: &dyn DefDatabase) -> bool { + pub fn is_block_module(self, db: &'db dyn DefDatabase) -> bool { self.block(db).is_some() && self.def_map(db).root_module_id() == self } } +impl ModuleId { + /// # Safety + /// + /// The caller must ensure that the `ModuleId` comes from the given database. + pub unsafe fn to_db<'db>(self, _db: &'db dyn DefDatabase) -> ModuleIdLt<'db> { + unsafe { std::mem::transmute(self) } + } +} + impl HasModule for ModuleId { #[inline] fn module(&self, _db: &dyn DefDatabase) -> ModuleId { diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres.rs index 3f29619bcb62..a85237662c43 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/nameres.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres.rs @@ -75,7 +75,7 @@ use triomphe::Arc; use tt::TextRange; use crate::{ - AstId, BlockId, BlockLoc, ExternCrateId, FunctionId, FxIndexMap, Lookup, MacroCallStyles, + AstId, BlockId, BlockIdLt, ExternCrateId, FunctionId, FxIndexMap, Lookup, MacroCallStyles, MacroExpander, MacroId, ModuleId, ModuleIdLt, ProcMacroId, UseId, db::DefDatabase, item_scope::{BuiltinShadowMode, ItemScope}, @@ -247,12 +247,12 @@ struct BlockInfo { parent: ModuleId, } -impl std::ops::Index for DefMap { +impl std::ops::Index> for DefMap { type Output = ModuleData; - fn index(&self, id: ModuleId) -> &ModuleData { + fn index(&self, id: ModuleIdLt<'_>) -> &ModuleData { self.modules - .get(&id) + .get(&unsafe { id.to_static() }) .unwrap_or_else(|| panic!("ModuleId not found in ModulesMap {:#?}: {id:#?}", self.root)) } } @@ -400,8 +400,10 @@ pub(crate) fn crate_local_def_map(db: &dyn DefDatabase, crate_id: Crate) -> DefM } #[salsa_macros::tracked(returns(ref))] -pub fn block_def_map(db: &dyn DefDatabase, block_id: BlockId) -> DefMap { - let BlockLoc { ast_id, module } = block_id.lookup(db); +pub fn block_def_map<'db>(db: &'db dyn DefDatabase, block_id: BlockIdLt<'db>) -> DefMap { + let block_id = unsafe { block_id.to_static() }; + let ast_id = block_id.ast_id(db); + let module = unsafe { block_id.module(db).to_static() }; let visibility = Visibility::Module(module, VisibilityExplicitness::Implicit); let module_data = @@ -557,7 +559,7 @@ impl DefMap { /// Returns the module containing `local_mod`, either the parent `mod`, or the module (or block) containing /// the block, if `self` corresponds to a block expression. - pub fn containing_module(&self, local_mod: ModuleId) -> Option { + pub fn containing_module(&self, local_mod: ModuleIdLt<'_>) -> Option { match self[local_mod].parent { Some(parent) => Some(parent), None => self.block.map(|BlockInfo { parent, .. }| parent), @@ -662,11 +664,11 @@ impl DefMap { /// /// If `f` returns `Some(val)`, iteration is stopped and `Some(val)` is returned. If `f` returns /// `None`, iteration continues. - pub(crate) fn with_ancestor_maps( + pub(crate) fn with_ancestor_maps<'db, T>( &self, - db: &dyn DefDatabase, - local_mod: ModuleId, - f: &mut dyn FnMut(&DefMap, ModuleId) -> Option, + db: &'db dyn DefDatabase, + local_mod: ModuleIdLt<'db>, + f: &mut dyn FnMut(&DefMap, ModuleIdLt<'db>) -> Option, ) -> Option { if let Some(it) = f(self, local_mod) { return Some(it); @@ -852,11 +854,13 @@ impl DerefMut for ModulesMap { } } -impl Index for ModulesMap { +impl Index> for ModulesMap { type Output = ModuleData; - fn index(&self, id: ModuleId) -> &ModuleData { - self.inner.get(&id).unwrap_or_else(|| panic!("ModuleId not found in ModulesMap: {id:#?}")) + fn index(&self, id: ModuleIdLt<'_>) -> &ModuleData { + self.inner + .get(&unsafe { id.to_static() }) + .unwrap_or_else(|| panic!("ModuleId not found in ModulesMap: {id:#?}")) } } diff --git a/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs b/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs index 263f603a0bfb..45d5dc9fcd27 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs @@ -881,7 +881,7 @@ impl<'db> Resolver<'db> { })); if let Some(block) = expr_scopes.block(scope_id) { let def_map = block_def_map(db, block); - let local_def_map = block.lookup(db).module.only_local_def_map(db); + let local_def_map = block.module(db).only_local_def_map(db); resolver.scopes.push(Scope::BlockScope(ModuleItemMap { def_map, local_def_map, @@ -1087,7 +1087,7 @@ fn resolver_for_scope_<'db>( for scope in scope_chain.into_iter().rev() { if let Some(block) = scopes.block(scope) { let def_map = block_def_map(db, block); - let local_def_map = block.lookup(db).module.only_local_def_map(db); + let local_def_map = block.module(db).only_local_def_map(db); // Using `DefMap::ROOT` is okay here since inside modules other than the root, // there can't directly be expressions. r = r.push_block_scope(def_map, local_def_map, def_map.root); diff --git a/src/tools/rust-analyzer/crates/hir-def/src/visibility.rs b/src/tools/rust-analyzer/crates/hir-def/src/visibility.rs index a1645de6ec23..95554c63b97d 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/visibility.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/visibility.rs @@ -9,8 +9,8 @@ use syntax::ast::{self, HasVisibility}; use triomphe::Arc; use crate::{ - AssocItemId, HasModule, ItemContainerId, LocalFieldId, ModuleId, TraitId, VariantId, - db::DefDatabase, nameres::DefMap, resolver::HasResolver, src::HasSource, + AssocItemId, HasModule, ItemContainerId, LocalFieldId, ModuleId, ModuleIdLt, TraitId, + VariantId, db::DefDatabase, nameres::DefMap, resolver::HasResolver, src::HasSource, }; pub use crate::item_tree::{RawVisibility, VisibilityExplicitness}; @@ -41,9 +41,13 @@ impl Visibility { } #[tracing::instrument(skip_all)] - pub fn is_visible_from(self, db: &dyn DefDatabase, from_module: ModuleId) -> bool { + pub fn is_visible_from<'db>( + self, + db: &'db dyn DefDatabase, + from_module: ModuleIdLt<'db>, + ) -> bool { let to_module = match self { - Visibility::Module(m, _) => m, + Visibility::Module(m, _) => unsafe { m.to_db(db) }, Visibility::PubCrate(krate) => return from_module.krate(db) == krate, Visibility::Public => return true, }; @@ -59,11 +63,11 @@ impl Visibility { Self::is_visible_from_def_map_(db, def_map, to_module, from_module) } - pub(crate) fn is_visible_from_def_map( + pub(crate) fn is_visible_from_def_map<'db>( self, - db: &dyn DefDatabase, - def_map: &DefMap, - from_module: ModuleId, + db: &'db dyn DefDatabase, + def_map: &'db DefMap, + from_module: ModuleIdLt<'db>, ) -> bool { if cfg!(debug_assertions) { _ = def_map.modules[from_module]; @@ -89,11 +93,11 @@ impl Visibility { Self::is_visible_from_def_map_(db, def_map, to_module, from_module) } - fn is_visible_from_def_map_( - db: &dyn DefDatabase, - def_map: &DefMap, - mut to_module: ModuleId, - mut from_module: ModuleId, + fn is_visible_from_def_map_<'db>( + db: &'db dyn DefDatabase, + def_map: &'db DefMap, + mut to_module: ModuleIdLt<'db>, + mut from_module: ModuleIdLt<'db>, ) -> bool { debug_assert_eq!(to_module.krate(db), def_map.krate()); // `to_module` might be the root module of a block expression. Those have the same diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs index cafe0329692c..70868e4b95aa 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs @@ -653,19 +653,16 @@ impl<'db> InferenceResult<'db> { } pub fn type_of_expr_with_adjust(&self, id: ExprId) -> Option> { match self.expr_adjustments.get(&id).and_then(|adjustments| { - adjustments - .iter() - .filter(|adj| { - // https://github.com/rust-lang/rust/blob/67819923ac8ea353aaa775303f4c3aacbf41d010/compiler/rustc_mir_build/src/thir/cx/expr.rs#L140 - !matches!( - adj, - Adjustment { - kind: Adjust::NeverToAny, - target, - } if target.is_never() - ) - }) - .next_back() + adjustments.iter().rfind(|adj| { + // https://github.com/rust-lang/rust/blob/67819923ac8ea353aaa775303f4c3aacbf41d010/compiler/rustc_mir_build/src/thir/cx/expr.rs#L140 + !matches!( + adj, + Adjustment { + kind: Adjust::NeverToAny, + target, + } if target.is_never() + ) + }) }) { Some(adjustment) => Some(adjustment.target), None => self.type_of_expr.get(id).copied(), diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs b/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs index 868ae00329b3..d9cfe6d84c2b 100644 --- a/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs +++ b/src/tools/rust-analyzer/crates/hir-ty/src/method_resolution.rs @@ -13,8 +13,8 @@ use tracing::{debug, instrument}; use base_db::Crate; use hir_def::{ - AssocItemId, BlockId, ConstId, FunctionId, GenericParamId, HasModule, ImplId, ItemContainerId, - ModuleId, TraitId, + AssocItemId, BlockIdLt, ConstId, FunctionId, GenericParamId, HasModule, ImplId, + ItemContainerId, ModuleId, TraitId, attrs::AttrFlags, expr_store::path::GenericArgs as HirGenericArgs, hir::ExprId, @@ -558,9 +558,9 @@ pub struct InherentImpls { } #[salsa::tracked] -impl InherentImpls { +impl<'db> InherentImpls { #[salsa::tracked(returns(ref))] - pub fn for_crate(db: &dyn HirDatabase, krate: Crate) -> Self { + pub fn for_crate(db: &'db dyn HirDatabase, krate: Crate) -> Self { let _p = tracing::info_span!("inherent_impls_in_crate_query", ?krate).entered(); let crate_def_map = crate_def_map(db, krate); @@ -569,7 +569,7 @@ impl InherentImpls { } #[salsa::tracked(returns(ref))] - pub fn for_block(db: &dyn HirDatabase, block: BlockId) -> Option> { + pub fn for_block(db: &'db dyn HirDatabase, block: BlockIdLt<'db>) -> Option> { let _p = tracing::info_span!("inherent_impls_in_block_query").entered(); let block_def_map = block_def_map(db, block); @@ -627,13 +627,13 @@ impl InherentImpls { self.map.get(self_ty).map(|it| &**it).unwrap_or_default() } - pub fn for_each_crate_and_block( - db: &dyn HirDatabase, + pub fn for_each_crate_and_block<'db>( + db: &'db dyn HirDatabase, krate: Crate, - block: Option, + block: Option>, for_each: &mut dyn FnMut(&InherentImpls), ) { - let blocks = std::iter::successors(block, |block| block.loc(db).module.block(db)); + let blocks = std::iter::successors(block, |block| block.module(db).block(db)); blocks.filter_map(|block| Self::for_block(db, block).as_deref()).for_each(&mut *for_each); for_each(Self::for_crate(db, krate)); } @@ -670,9 +670,9 @@ pub struct TraitImpls { } #[salsa::tracked] -impl TraitImpls { +impl<'db> TraitImpls { #[salsa::tracked(returns(ref))] - pub fn for_crate(db: &dyn HirDatabase, krate: Crate) -> Arc { + pub fn for_crate(db: &'db dyn HirDatabase, krate: Crate) -> Arc { let _p = tracing::info_span!("inherent_impls_in_crate_query", ?krate).entered(); let crate_def_map = crate_def_map(db, krate); @@ -681,7 +681,7 @@ impl TraitImpls { } #[salsa::tracked(returns(ref))] - pub fn for_block(db: &dyn HirDatabase, block: BlockId) -> Option> { + pub fn for_block(db: &'db dyn HirDatabase, block: BlockIdLt<'db>) -> Option> { let _p = tracing::info_span!("inherent_impls_in_block_query").entered(); let block_def_map = block_def_map(db, block); @@ -690,7 +690,7 @@ impl TraitImpls { } #[salsa::tracked(returns(ref))] - pub fn for_crate_and_deps(db: &dyn HirDatabase, krate: Crate) -> Box<[Arc]> { + pub fn for_crate_and_deps(db: &'db dyn HirDatabase, krate: Crate) -> Box<[Arc]> { krate.transitive_deps(db).iter().map(|&dep| Self::for_crate(db, dep).clone()).collect() } } @@ -792,23 +792,23 @@ impl TraitImpls { } } - pub fn for_each_crate_and_block( - db: &dyn HirDatabase, + pub fn for_each_crate_and_block<'db>( + db: &'db dyn HirDatabase, krate: Crate, - block: Option, + block: Option>, for_each: &mut dyn FnMut(&TraitImpls), ) { - let blocks = std::iter::successors(block, |block| block.loc(db).module.block(db)); + let blocks = std::iter::successors(block, |block| block.module(db).block(db)); blocks.filter_map(|block| Self::for_block(db, block).as_deref()).for_each(&mut *for_each); Self::for_crate_and_deps(db, krate).iter().map(|it| &**it).for_each(for_each); } /// Like [`Self::for_each_crate_and_block()`], but takes in account two blocks, one for a trait and one for a self type. - pub fn for_each_crate_and_block_trait_and_type( - db: &dyn HirDatabase, + pub fn for_each_crate_and_block_trait_and_type<'db>( + db: &'db dyn HirDatabase, krate: Crate, - type_block: Option, - trait_block: Option, + type_block: Option>, + trait_block: Option>, for_each: &mut dyn FnMut(&TraitImpls), ) { let in_self_and_deps = TraitImpls::for_crate_and_deps(db, krate); @@ -819,10 +819,11 @@ impl TraitImpls { // that means there can't be duplicate impls; if they meet, we stop the search of the deeper block. // This breaks when they are equal (both will stop immediately), therefore we handle this case // specifically. - let blocks_iter = |block: Option| { - std::iter::successors(block, |block| block.loc(db).module.block(db)) + let blocks_iter = |block: Option>| { + std::iter::successors(block, |block| block.module(db).block(db)) }; - let for_each_block = |current_block: Option, other_block: Option| { + let for_each_block = |current_block: Option>, + other_block: Option>| { blocks_iter(current_block) .take_while(move |&block| { other_block.is_none_or(|other_block| other_block != block) diff --git a/src/tools/rust-analyzer/crates/hir/src/lib.rs b/src/tools/rust-analyzer/crates/hir/src/lib.rs index 56560e24c08c..e57f031f009a 100644 --- a/src/tools/rust-analyzer/crates/hir/src/lib.rs +++ b/src/tools/rust-analyzer/crates/hir/src/lib.rs @@ -559,7 +559,7 @@ impl Module { /// in the module tree of any target in `Cargo.toml`. pub fn crate_root(self, db: &dyn HirDatabase) -> Module { let def_map = crate_def_map(db, self.id.krate(db)); - Module { id: def_map.crate_root(db).into() } + Module { id: def_map.crate_root(db) } } pub fn is_crate_root(self, db: &dyn HirDatabase) -> bool { @@ -590,7 +590,7 @@ impl Module { while id.is_block_module(db) { id = id.containing_module(db).expect("block without parent module"); } - Module { id } + Module { id: unsafe { id.to_static() } } } pub fn path_to_root(self, db: &dyn HirDatabase) -> Vec { @@ -2475,7 +2475,7 @@ impl Function { GenericArgs::new_from_iter(interner, []), ParamEnvAndCrate { param_env: db.trait_environment(self.id.into()), - krate: self.id.module(db).krate(), + krate: self.id.module(db).krate(db), }, )?; let (result, output) = interpret_mir(db, body, false, None)?; @@ -4352,7 +4352,7 @@ impl Impl { module.block(db), &mut |impls| extend_with_impls(impls.for_self_ty(&simplified_ty)), ); - std::iter::successors(module.block(db), |block| block.loc(db).module.block(db)) + std::iter::successors(module.block(db), |block| block.module(db).block(db)) .filter_map(|block| TraitImpls::for_block(db, block).as_deref()) .for_each(|impls| impls.for_self_ty(&simplified_ty, &mut extend_with_impls)); for &krate in &**db.all_crates() { diff --git a/src/tools/rust-analyzer/crates/hir/src/semantics/child_by_source.rs b/src/tools/rust-analyzer/crates/hir/src/semantics/child_by_source.rs index c1f72debe54f..d924aaa25ddc 100644 --- a/src/tools/rust-analyzer/crates/hir/src/semantics/child_by_source.rs +++ b/src/tools/rust-analyzer/crates/hir/src/semantics/child_by_source.rs @@ -226,7 +226,7 @@ impl ChildBySource for DefWithBodyId { // All block expressions are merged into the same map, because they logically all add // inner items to the containing `DefWithBodyId`. def_map[def_map.root].scope.child_by_source_to(db, res, file_id); - res[keys::BLOCK].insert(block.lookup(db).ast_id.to_ptr(db), block); + res[keys::BLOCK].insert(block.ast_id(db).to_ptr(db), block); } } }