mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-27 05:23:24 +00:00
Auto merge of #15053 - Veykril:crate-root-module-id, r=Veykril
internal: Add a CrateRootModuleId that encodes a module id that is always a crate root
This commit is contained in:
commit
9c967d3809
9 changed files with 102 additions and 65 deletions
|
@ -81,7 +81,7 @@ fn find_path_inner(
|
|||
}
|
||||
|
||||
let def_map = from.def_map(db);
|
||||
let crate_root = def_map.crate_root();
|
||||
let crate_root = def_map.crate_root().into();
|
||||
// - if the item is a module, jump straight to module search
|
||||
if let ItemInNs::Types(ModuleDefId::ModuleId(module_id)) = item {
|
||||
let mut visited_modules = FxHashSet::default();
|
||||
|
@ -374,7 +374,7 @@ fn calculate_best_path(
|
|||
}
|
||||
}
|
||||
if let Some(module) = item.module(db) {
|
||||
if module.def_map(db).block_id().is_some() && prefixed.is_some() {
|
||||
if module.containing_block().is_some() && prefixed.is_some() {
|
||||
cov_mark::hit!(prefixed_in_block_expression);
|
||||
prefixed = Some(PrefixKind::Plain);
|
||||
}
|
||||
|
|
|
@ -101,7 +101,6 @@ pub struct ItemTree {
|
|||
top_level: SmallVec<[ModItem; 1]>,
|
||||
attrs: FxHashMap<AttrOwner, RawAttrs>,
|
||||
|
||||
// FIXME: Remove this indirection, an item tree is almost always non-empty?
|
||||
data: Option<Box<ItemTreeData>>,
|
||||
}
|
||||
|
||||
|
@ -718,7 +717,6 @@ pub struct Mod {
|
|||
pub enum ModKind {
|
||||
/// `mod m { ... }`
|
||||
Inline { items: Box<[ModItem]> },
|
||||
|
||||
/// `mod m;`
|
||||
Outline,
|
||||
}
|
||||
|
@ -892,10 +890,6 @@ impl ModItem {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn downcast<N: ItemTreeNode>(self) -> Option<FileItemTreeId<N>> {
|
||||
N::id_from_mod_item(self)
|
||||
}
|
||||
|
||||
pub fn ast_id(&self, tree: &ItemTree) -> FileAstId<ast::Item> {
|
||||
match self {
|
||||
ModItem::Import(it) => tree[it.index].ast_id().upcast(),
|
||||
|
|
|
@ -93,6 +93,46 @@ use crate::{
|
|||
},
|
||||
};
|
||||
|
||||
/// A `ModuleId` that is always a crate's root module.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub struct CrateRootModuleId {
|
||||
krate: CrateId,
|
||||
}
|
||||
|
||||
impl CrateRootModuleId {
|
||||
pub fn def_map(&self, db: &dyn db::DefDatabase) -> Arc<DefMap> {
|
||||
db.crate_def_map(self.krate)
|
||||
}
|
||||
|
||||
pub fn krate(self) -> CrateId {
|
||||
self.krate
|
||||
}
|
||||
}
|
||||
|
||||
impl From<CrateRootModuleId> for ModuleId {
|
||||
fn from(CrateRootModuleId { krate }: CrateRootModuleId) -> Self {
|
||||
ModuleId { krate, block: None, local_id: DefMap::ROOT }
|
||||
}
|
||||
}
|
||||
|
||||
impl From<CrateRootModuleId> for ModuleDefId {
|
||||
fn from(value: CrateRootModuleId) -> Self {
|
||||
ModuleDefId::ModuleId(value.into())
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<ModuleId> for CrateRootModuleId {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(ModuleId { krate, block, local_id }: ModuleId) -> Result<Self, Self::Error> {
|
||||
if block.is_none() && local_id == DefMap::ROOT {
|
||||
Ok(CrateRootModuleId { krate })
|
||||
} else {
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub struct ModuleId {
|
||||
krate: CrateId,
|
||||
|
@ -314,8 +354,7 @@ impl_intern!(MacroRulesId, MacroRulesLoc, intern_macro_rules, lookup_intern_macr
|
|||
pub struct ProcMacroId(salsa::InternId);
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub struct ProcMacroLoc {
|
||||
// FIXME: this should be a crate? or just a crate-root module
|
||||
pub container: ModuleId,
|
||||
pub container: CrateRootModuleId,
|
||||
pub id: ItemTreeId<Function>,
|
||||
pub expander: ProcMacroExpander,
|
||||
pub kind: ProcMacroKind,
|
||||
|
@ -903,7 +942,7 @@ impl HasModule for MacroId {
|
|||
match self {
|
||||
MacroId::MacroRulesId(it) => it.lookup(db).container,
|
||||
MacroId::Macro2Id(it) => it.lookup(db).container,
|
||||
MacroId::ProcMacroId(it) => it.lookup(db).container,
|
||||
MacroId::ProcMacroId(it) => it.lookup(db).container.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -77,8 +77,8 @@ use crate::{
|
|||
path::ModPath,
|
||||
per_ns::PerNs,
|
||||
visibility::Visibility,
|
||||
AstId, BlockId, BlockLoc, FunctionId, LocalModuleId, Lookup, MacroExpander, MacroId, ModuleId,
|
||||
ProcMacroId,
|
||||
AstId, BlockId, BlockLoc, CrateRootModuleId, FunctionId, LocalModuleId, Lookup, MacroExpander,
|
||||
MacroId, ModuleId, ProcMacroId,
|
||||
};
|
||||
|
||||
/// Contains the results of (early) name resolution.
|
||||
|
@ -93,7 +93,10 @@ use crate::{
|
|||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub struct DefMap {
|
||||
_c: Count<Self>,
|
||||
/// When this is a block def map, this will hold the block id of the the block and module that
|
||||
/// contains this block.
|
||||
block: Option<BlockInfo>,
|
||||
/// The modules and their data declared in this crate.
|
||||
modules: Arena<ModuleData>,
|
||||
krate: CrateId,
|
||||
/// The prelude module for this crate. This either comes from an import
|
||||
|
@ -111,15 +114,18 @@ pub struct DefMap {
|
|||
/// attributes.
|
||||
derive_helpers_in_scope: FxHashMap<AstId<ast::Item>, Vec<(Name, MacroId, MacroCallId)>>,
|
||||
|
||||
/// The diagnostics that need to be emitted for this crate.
|
||||
diagnostics: Vec<DefDiagnostic>,
|
||||
|
||||
/// The crate data that is shared between a crate's def map and all its block def maps.
|
||||
data: Arc<DefMapCrateData>,
|
||||
}
|
||||
|
||||
/// Data that belongs to a crate which is shared between a crate's def map and all its block def maps.
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
struct DefMapCrateData {
|
||||
extern_prelude: FxHashMap<Name, ModuleId>,
|
||||
/// The extern prelude which contains all root modules of external crates that are in scope.
|
||||
extern_prelude: FxHashMap<Name, CrateRootModuleId>,
|
||||
|
||||
/// Side table for resolving derive helpers.
|
||||
exported_derives: FxHashMap<MacroDefId, Box<[Name]>>,
|
||||
|
@ -279,6 +285,7 @@ pub struct ModuleData {
|
|||
}
|
||||
|
||||
impl DefMap {
|
||||
/// The module id of a crate or block root.
|
||||
pub const ROOT: LocalModuleId = LocalModuleId::from_raw(la_arena::RawIdx::from_u32(0));
|
||||
|
||||
pub(crate) fn crate_def_map_query(db: &dyn DefDatabase, krate: CrateId) -> Arc<DefMap> {
|
||||
|
@ -419,11 +426,11 @@ impl DefMap {
|
|||
}
|
||||
|
||||
pub(crate) fn extern_prelude(&self) -> impl Iterator<Item = (&Name, ModuleId)> + '_ {
|
||||
self.data.extern_prelude.iter().map(|(name, def)| (name, *def))
|
||||
self.data.extern_prelude.iter().map(|(name, &def)| (name, def.into()))
|
||||
}
|
||||
|
||||
pub(crate) fn macro_use_prelude(&self) -> impl Iterator<Item = (&Name, MacroId)> + '_ {
|
||||
self.macro_use_prelude.iter().map(|(name, def)| (name, *def))
|
||||
self.macro_use_prelude.iter().map(|(name, &def)| (name, def))
|
||||
}
|
||||
|
||||
pub fn module_id(&self, local_id: LocalModuleId) -> ModuleId {
|
||||
|
@ -431,8 +438,8 @@ impl DefMap {
|
|||
ModuleId { krate: self.krate, local_id, block }
|
||||
}
|
||||
|
||||
pub(crate) fn crate_root(&self) -> ModuleId {
|
||||
ModuleId { krate: self.krate, block: None, local_id: DefMap::ROOT }
|
||||
pub fn crate_root(&self) -> CrateRootModuleId {
|
||||
CrateRootModuleId { krate: self.krate }
|
||||
}
|
||||
|
||||
pub(crate) fn resolve_path(
|
||||
|
@ -476,7 +483,7 @@ impl DefMap {
|
|||
///
|
||||
/// If `f` returns `Some(val)`, iteration is stopped and `Some(val)` is returned. If `f` returns
|
||||
/// `None`, iteration continues.
|
||||
pub fn with_ancestor_maps<T>(
|
||||
pub(crate) fn with_ancestor_maps<T>(
|
||||
&self,
|
||||
db: &dyn DefDatabase,
|
||||
local_mod: LocalModuleId,
|
||||
|
|
|
@ -51,11 +51,11 @@ use crate::{
|
|||
per_ns::PerNs,
|
||||
tt,
|
||||
visibility::{RawVisibility, Visibility},
|
||||
AdtId, AstId, AstIdWithPath, ConstLoc, EnumLoc, EnumVariantId, ExternBlockLoc, FunctionId,
|
||||
FunctionLoc, ImplLoc, Intern, ItemContainerId, LocalModuleId, Macro2Id, Macro2Loc,
|
||||
MacroExpander, MacroId, MacroRulesId, MacroRulesLoc, ModuleDefId, ModuleId, ProcMacroId,
|
||||
ProcMacroLoc, StaticLoc, StructLoc, TraitAliasLoc, TraitLoc, TypeAliasLoc, UnionLoc,
|
||||
UnresolvedMacro,
|
||||
AdtId, AstId, AstIdWithPath, ConstLoc, CrateRootModuleId, EnumLoc, EnumVariantId,
|
||||
ExternBlockLoc, FunctionId, FunctionLoc, ImplLoc, Intern, ItemContainerId, LocalModuleId,
|
||||
Macro2Id, Macro2Loc, MacroExpander, MacroId, MacroRulesId, MacroRulesLoc, ModuleDefId,
|
||||
ModuleId, ProcMacroId, ProcMacroLoc, StaticLoc, StructLoc, TraitAliasLoc, TraitLoc,
|
||||
TypeAliasLoc, UnionLoc, UnresolvedMacro,
|
||||
};
|
||||
|
||||
static GLOB_RECURSION_LIMIT: Limit = Limit::new(100);
|
||||
|
@ -274,8 +274,6 @@ impl DefCollector<'_> {
|
|||
|
||||
let file_id = self.db.crate_graph()[self.def_map.krate].root_file_id;
|
||||
let item_tree = self.db.file_item_tree(file_id.into());
|
||||
let module_id = DefMap::ROOT;
|
||||
|
||||
let attrs = item_tree.top_level_attrs(self.db, self.def_map.krate);
|
||||
let crate_data = Arc::get_mut(&mut self.def_map.data).unwrap();
|
||||
|
||||
|
@ -285,10 +283,9 @@ impl DefCollector<'_> {
|
|||
|
||||
for (name, dep) in &self.deps {
|
||||
if dep.is_prelude() {
|
||||
crate_data.extern_prelude.insert(
|
||||
name.clone(),
|
||||
ModuleId { krate: dep.crate_id, block: None, local_id: DefMap::ROOT },
|
||||
);
|
||||
crate_data
|
||||
.extern_prelude
|
||||
.insert(name.clone(), CrateRootModuleId { krate: dep.crate_id });
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -374,7 +371,7 @@ impl DefCollector<'_> {
|
|||
ModCollector {
|
||||
def_collector: self,
|
||||
macro_depth: 0,
|
||||
module_id,
|
||||
module_id: DefMap::ROOT,
|
||||
tree_id: TreeId::new(file_id.into(), None),
|
||||
item_tree: &item_tree,
|
||||
mod_dir: ModDir::root(),
|
||||
|
@ -384,8 +381,6 @@ impl DefCollector<'_> {
|
|||
|
||||
fn seed_with_inner(&mut self, tree_id: TreeId) {
|
||||
let item_tree = tree_id.item_tree(self.db);
|
||||
let module_id = DefMap::ROOT;
|
||||
|
||||
let is_cfg_enabled = item_tree
|
||||
.top_level_attrs(self.db, self.def_map.krate)
|
||||
.cfg()
|
||||
|
@ -394,7 +389,7 @@ impl DefCollector<'_> {
|
|||
ModCollector {
|
||||
def_collector: self,
|
||||
macro_depth: 0,
|
||||
module_id,
|
||||
module_id: DefMap::ROOT,
|
||||
tree_id,
|
||||
item_tree: &item_tree,
|
||||
mod_dir: ModDir::root(),
|
||||
|
@ -604,8 +599,6 @@ impl DefCollector<'_> {
|
|||
if self.def_map.block.is_some() {
|
||||
return;
|
||||
}
|
||||
let crate_root = self.def_map.module_id(DefMap::ROOT);
|
||||
|
||||
let kind = def.kind.to_basedb_kind();
|
||||
let (expander, kind) =
|
||||
match self.proc_macros.as_ref().map(|it| it.iter().find(|(n, _)| n == &def.name)) {
|
||||
|
@ -614,7 +607,8 @@ impl DefCollector<'_> {
|
|||
};
|
||||
|
||||
let proc_macro_id =
|
||||
ProcMacroLoc { container: crate_root, id, expander, kind }.intern(self.db);
|
||||
ProcMacroLoc { container: self.def_map.crate_root(), id, expander, kind }
|
||||
.intern(self.db);
|
||||
self.define_proc_macro(def.name.clone(), proc_macro_id);
|
||||
let crate_data = Arc::get_mut(&mut self.def_map.data).unwrap();
|
||||
if let ProcMacroKind::CustomDerive { helpers } = def.kind {
|
||||
|
@ -831,16 +825,12 @@ impl DefCollector<'_> {
|
|||
}
|
||||
}
|
||||
|
||||
fn resolve_extern_crate(&self, name: &Name) -> Option<ModuleId> {
|
||||
fn resolve_extern_crate(&self, name: &Name) -> Option<CrateRootModuleId> {
|
||||
if *name == name!(self) {
|
||||
cov_mark::hit!(extern_crate_self_as);
|
||||
Some(self.def_map.crate_root())
|
||||
} else {
|
||||
self.deps.get(name).map(|dep| ModuleId {
|
||||
krate: dep.crate_id,
|
||||
block: None,
|
||||
local_id: DefMap::ROOT,
|
||||
})
|
||||
self.deps.get(name).map(|dep| CrateRootModuleId { krate: dep.crate_id })
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -883,10 +873,12 @@ impl DefCollector<'_> {
|
|||
{
|
||||
if let (Some(ModuleDefId::ModuleId(def)), Some(name)) = (def.take_types(), name)
|
||||
{
|
||||
Arc::get_mut(&mut self.def_map.data)
|
||||
.unwrap()
|
||||
.extern_prelude
|
||||
.insert(name.clone(), def);
|
||||
if let Ok(def) = def.try_into() {
|
||||
Arc::get_mut(&mut self.def_map.data)
|
||||
.unwrap()
|
||||
.extern_prelude
|
||||
.insert(name.clone(), def);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1791,13 +1783,11 @@ impl ModCollector<'_, '_> {
|
|||
|
||||
let target_crate =
|
||||
match self.def_collector.resolve_extern_crate(&self.item_tree[extern_crate].name) {
|
||||
Some(m) => {
|
||||
if m == self.def_collector.def_map.module_id(self.module_id) {
|
||||
cov_mark::hit!(ignore_macro_use_extern_crate_self);
|
||||
return;
|
||||
}
|
||||
m.krate
|
||||
Some(m) if m.krate == self.def_collector.def_map.krate => {
|
||||
cov_mark::hit!(ignore_macro_use_extern_crate_self);
|
||||
return;
|
||||
}
|
||||
Some(m) => m.krate,
|
||||
None => return,
|
||||
};
|
||||
|
||||
|
|
|
@ -21,11 +21,11 @@ use crate::{
|
|||
path::{ModPath, Path, PathKind},
|
||||
per_ns::PerNs,
|
||||
visibility::{RawVisibility, Visibility},
|
||||
AdtId, AssocItemId, ConstId, ConstParamId, DefWithBodyId, EnumId, EnumVariantId, ExternBlockId,
|
||||
FunctionId, GenericDefId, GenericParamId, HasModule, ImplId, ItemContainerId, LifetimeParamId,
|
||||
LocalModuleId, Lookup, Macro2Id, MacroId, MacroRulesId, ModuleDefId, ModuleId, ProcMacroId,
|
||||
StaticId, StructId, TraitAliasId, TraitId, TypeAliasId, TypeOrConstParamId, TypeOwnerId,
|
||||
TypeParamId, VariantId,
|
||||
AdtId, AssocItemId, ConstId, ConstParamId, CrateRootModuleId, DefWithBodyId, EnumId,
|
||||
EnumVariantId, ExternBlockId, FunctionId, GenericDefId, GenericParamId, HasModule, ImplId,
|
||||
ItemContainerId, LifetimeParamId, LocalModuleId, Lookup, Macro2Id, MacroId, MacroRulesId,
|
||||
ModuleDefId, ModuleId, ProcMacroId, StaticId, StructId, TraitAliasId, TraitId, TypeAliasId,
|
||||
TypeOrConstParamId, TypeOwnerId, TypeParamId, VariantId,
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
|
@ -946,6 +946,15 @@ impl HasResolver for ModuleId {
|
|||
}
|
||||
}
|
||||
|
||||
impl HasResolver for CrateRootModuleId {
|
||||
fn resolver(self, db: &dyn DefDatabase) -> Resolver {
|
||||
Resolver {
|
||||
scopes: vec![],
|
||||
module_scope: ModuleItemMap { def_map: self.def_map(db), module_id: DefMap::ROOT },
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl HasResolver for TraitId {
|
||||
fn resolver(self, db: &dyn DefDatabase) -> Resolver {
|
||||
self.lookup(db).container.resolver(db).push_generic_params_scope(db, self.into())
|
||||
|
|
|
@ -20,7 +20,7 @@ use syntax::{ast, AstNode, AstPtr, SyntaxNode, SyntaxNodePtr};
|
|||
/// `AstId` points to an AST node in a specific file.
|
||||
pub struct FileAstId<N: AstNode> {
|
||||
raw: ErasedFileAstId,
|
||||
_ty: PhantomData<fn() -> N>,
|
||||
covariant: PhantomData<fn() -> N>,
|
||||
}
|
||||
|
||||
impl<N: AstNode> Clone for FileAstId<N> {
|
||||
|
@ -54,7 +54,7 @@ impl<N: AstNode> FileAstId<N> {
|
|||
where
|
||||
N: Into<M>,
|
||||
{
|
||||
FileAstId { raw: self.raw, _ty: PhantomData }
|
||||
FileAstId { raw: self.raw, covariant: PhantomData }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -122,7 +122,7 @@ impl AstIdMap {
|
|||
|
||||
pub fn ast_id<N: AstNode>(&self, item: &N) -> FileAstId<N> {
|
||||
let raw = self.erased_ast_id(item.syntax());
|
||||
FileAstId { raw, _ty: PhantomData }
|
||||
FileAstId { raw, covariant: PhantomData }
|
||||
}
|
||||
|
||||
pub fn get<N: AstNode>(&self, id: FileAstId<N>) -> AstPtr<N> {
|
||||
|
|
|
@ -203,7 +203,7 @@ impl Crate {
|
|||
|
||||
pub fn root_module(self, db: &dyn HirDatabase) -> Module {
|
||||
let def_map = db.crate_def_map(self.id);
|
||||
Module { id: def_map.module_id(DefMap::ROOT) }
|
||||
Module { id: def_map.crate_root().into() }
|
||||
}
|
||||
|
||||
pub fn modules(self, db: &dyn HirDatabase) -> Vec<Module> {
|
||||
|
@ -476,7 +476,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 = db.crate_def_map(self.id.krate());
|
||||
Module { id: def_map.module_id(DefMap::ROOT) }
|
||||
Module { id: def_map.crate_root().into() }
|
||||
}
|
||||
|
||||
pub fn is_crate_root(self) -> bool {
|
||||
|
|
|
@ -554,7 +554,6 @@ impl GlobalState {
|
|||
self.vfs_progress_n_total = n_total;
|
||||
self.vfs_progress_n_done = n_done;
|
||||
|
||||
// if n_total != 0 {
|
||||
let state = if n_done == 0 {
|
||||
Progress::Begin
|
||||
} else if n_done < n_total {
|
||||
|
@ -570,7 +569,6 @@ impl GlobalState {
|
|||
Some(Progress::fraction(n_done, n_total)),
|
||||
None,
|
||||
);
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue