Turn BlockLoc into a tracked struct

This commit is contained in:
Lukas Wirth 2025-11-30 13:56:00 +01:00
parent 7766ee6869
commit a1a9514f6f
14 changed files with 214 additions and 146 deletions

View file

@ -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]

View file

@ -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) =

View file

@ -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::<syntax::ast::generated::nodes::BlockExpr>(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::<syntax::ast::generated::nodes::BlockExpr>(ErasedFileAstId { kind: BlockExpr, index: 0, hash: C181 }),
},
module: ModuleIdLt {
[salsa id]: Id(3000),
krate: Crate(
Id(1c00),
),
block: None,
},
},
),
},
},
),
}"#]],
);

View file

@ -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<usize>,
}
/// 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<ModPath> {
// - 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<Choice> {
@ -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<Name> {
@ -278,7 +278,7 @@ fn find_in_prelude(
db: &dyn DefDatabase,
local_def_map: &DefMap,
item: ItemInNs,
from: ModuleId,
from: ModuleIdLt<'_>,
) -> Option<Choice> {
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<PathKind> {
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<Choice>,
@ -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<Choice>,
@ -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<Choice>,
@ -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<Choice>,
@ -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;

View file

@ -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);

View file

@ -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<Arc<ItemTree>> = 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()

View file

@ -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<ast::BlockExpr>,
/// 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<BlockId>,
pub block: Option<BlockIdLt<'db>>,
}
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<Name> {
pub fn name(self, db: &'db dyn DefDatabase) -> Option<Name> {
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<ModuleId> {
pub fn containing_module(self, db: &'db dyn DefDatabase) -> Option<ModuleIdLt<'db>> {
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 {

View file

@ -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<ModuleId> for DefMap {
impl std::ops::Index<ModuleIdLt<'_>> 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<ModuleId> {
pub fn containing_module(&self, local_mod: ModuleIdLt<'_>) -> Option<ModuleId> {
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<T>(
pub(crate) fn with_ancestor_maps<'db, T>(
&self,
db: &dyn DefDatabase,
local_mod: ModuleId,
f: &mut dyn FnMut(&DefMap, ModuleId) -> Option<T>,
db: &'db dyn DefDatabase,
local_mod: ModuleIdLt<'db>,
f: &mut dyn FnMut(&DefMap, ModuleIdLt<'db>) -> Option<T>,
) -> Option<T> {
if let Some(it) = f(self, local_mod) {
return Some(it);
@ -852,11 +854,13 @@ impl DerefMut for ModulesMap {
}
}
impl Index<ModuleId> for ModulesMap {
impl Index<ModuleIdLt<'_>> 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:#?}"))
}
}

View file

@ -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);

View file

@ -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

View file

@ -653,19 +653,16 @@ impl<'db> InferenceResult<'db> {
}
pub fn type_of_expr_with_adjust(&self, id: ExprId) -> Option<Ty<'db>> {
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(),

View file

@ -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<Box<Self>> {
pub fn for_block(db: &'db dyn HirDatabase, block: BlockIdLt<'db>) -> Option<Box<Self>> {
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<BlockId>,
block: Option<BlockIdLt<'db>>,
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<Self> {
pub fn for_crate(db: &'db dyn HirDatabase, krate: Crate) -> Arc<Self> {
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<Box<Self>> {
pub fn for_block(db: &'db dyn HirDatabase, block: BlockIdLt<'db>) -> Option<Box<Self>> {
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<Self>]> {
pub fn for_crate_and_deps(db: &'db dyn HirDatabase, krate: Crate) -> Box<[Arc<Self>]> {
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<BlockId>,
block: Option<BlockIdLt<'db>>,
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<BlockId>,
trait_block: Option<BlockId>,
type_block: Option<BlockIdLt<'db>>,
trait_block: Option<BlockIdLt<'db>>,
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<BlockId>| {
std::iter::successors(block, |block| block.loc(db).module.block(db))
let blocks_iter = |block: Option<BlockIdLt<'db>>| {
std::iter::successors(block, |block| block.module(db).block(db))
};
let for_each_block = |current_block: Option<BlockId>, other_block: Option<BlockId>| {
let for_each_block = |current_block: Option<BlockIdLt<'db>>,
other_block: Option<BlockIdLt<'db>>| {
blocks_iter(current_block)
.take_while(move |&block| {
other_block.is_none_or(|other_block| other_block != block)

View file

@ -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<Module> {
@ -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() {

View file

@ -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);
}
}
}