Turn BlockLoc into a tracked struct
This commit is contained in:
parent
7766ee6869
commit
a1a9514f6f
14 changed files with 214 additions and 146 deletions
|
|
@ -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]
|
||||
|
|
|
|||
|
|
@ -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) =
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
},
|
||||
},
|
||||
),
|
||||
},
|
||||
},
|
||||
),
|
||||
}"#]],
|
||||
);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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:#?}"))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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(),
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue