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:
bors 2023-06-14 14:41:06 +00:00
commit 9c967d3809
9 changed files with 102 additions and 65 deletions

View file

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

View file

@ -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(),

View file

@ -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(),
}
}
}

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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