mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-28 05:53:45 +00:00
Auto merge of #14941 - Veykril:def-map, r=Veykril
Shrink `DefMap`, share crate level items with block def maps
This commit is contained in:
commit
0b4c09b1d2
25 changed files with 296 additions and 233 deletions
|
@ -1075,7 +1075,7 @@ impl ExprCollector<'_> {
|
||||||
match block_id.map(|block_id| (self.db.block_def_map(block_id), block_id)) {
|
match block_id.map(|block_id| (self.db.block_def_map(block_id), block_id)) {
|
||||||
Some((def_map, block_id)) => {
|
Some((def_map, block_id)) => {
|
||||||
self.body.block_scopes.push(block_id);
|
self.body.block_scopes.push(block_id);
|
||||||
(def_map.module_id(def_map.root()), def_map)
|
(def_map.module_id(DefMap::ROOT), def_map)
|
||||||
}
|
}
|
||||||
None => (self.expander.module, self.def_map.clone()),
|
None => (self.expander.module, self.def_map.clone()),
|
||||||
};
|
};
|
||||||
|
|
|
@ -148,8 +148,8 @@ fn f() {
|
||||||
}
|
}
|
||||||
"#,
|
"#,
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
BlockId(1) in ModuleId { krate: Idx::<CrateData>(0), block: Some(BlockId(0)), local_id: Idx::<ModuleData>(1) }
|
BlockId(1) in BlockRelativeModuleId { block: Some(BlockId(0)), local_id: Idx::<ModuleData>(1) }
|
||||||
BlockId(0) in ModuleId { krate: Idx::<CrateData>(0), block: None, local_id: Idx::<ModuleData>(0) }
|
BlockId(0) in BlockRelativeModuleId { block: None, local_id: Idx::<ModuleData>(0) }
|
||||||
crate scope
|
crate scope
|
||||||
"#]],
|
"#]],
|
||||||
);
|
);
|
||||||
|
|
|
@ -12,6 +12,7 @@ use crate::{
|
||||||
db::DefDatabase,
|
db::DefDatabase,
|
||||||
dyn_map::{keys, DynMap},
|
dyn_map::{keys, DynMap},
|
||||||
item_scope::ItemScope,
|
item_scope::ItemScope,
|
||||||
|
nameres::DefMap,
|
||||||
src::{HasChildSource, HasSource},
|
src::{HasChildSource, HasSource},
|
||||||
AdtId, AssocItemId, DefWithBodyId, EnumId, EnumVariantId, FieldId, ImplId, Lookup, MacroId,
|
AdtId, AssocItemId, DefWithBodyId, EnumId, EnumVariantId, FieldId, ImplId, Lookup, MacroId,
|
||||||
ModuleDefId, ModuleId, TraitId, VariantId,
|
ModuleDefId, ModuleId, TraitId, VariantId,
|
||||||
|
@ -205,7 +206,7 @@ impl ChildBySource for DefWithBodyId {
|
||||||
for (_, def_map) in body.blocks(db) {
|
for (_, def_map) in body.blocks(db) {
|
||||||
// All block expressions are merged into the same map, because they logically all add
|
// All block expressions are merged into the same map, because they logically all add
|
||||||
// inner items to the containing `DefWithBodyId`.
|
// inner items to the containing `DefWithBodyId`.
|
||||||
def_map[def_map.root()].scope.child_by_source_to(db, res, file_id);
|
def_map[DefMap::ROOT].scope.child_by_source_to(db, res, file_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -198,15 +198,14 @@ pub trait DefDatabase: InternDatabase + ExpandDatabase + Upcast<dyn ExpandDataba
|
||||||
|
|
||||||
// endregion:attrs
|
// endregion:attrs
|
||||||
|
|
||||||
#[salsa::invoke(LangItems::crate_lang_items_query)]
|
|
||||||
fn crate_lang_items(&self, krate: CrateId) -> Arc<LangItems>;
|
|
||||||
|
|
||||||
#[salsa::invoke(LangItems::lang_item_query)]
|
#[salsa::invoke(LangItems::lang_item_query)]
|
||||||
fn lang_item(&self, start_crate: CrateId, item: LangItem) -> Option<LangItemTarget>;
|
fn lang_item(&self, start_crate: CrateId, item: LangItem) -> Option<LangItemTarget>;
|
||||||
|
|
||||||
#[salsa::invoke(ImportMap::import_map_query)]
|
#[salsa::invoke(ImportMap::import_map_query)]
|
||||||
fn import_map(&self, krate: CrateId) -> Arc<ImportMap>;
|
fn import_map(&self, krate: CrateId) -> Arc<ImportMap>;
|
||||||
|
|
||||||
|
// region:visibilities
|
||||||
|
|
||||||
#[salsa::invoke(visibility::field_visibilities_query)]
|
#[salsa::invoke(visibility::field_visibilities_query)]
|
||||||
fn field_visibilities(&self, var: VariantId) -> Arc<ArenaMap<LocalFieldId, Visibility>>;
|
fn field_visibilities(&self, var: VariantId) -> Arc<ArenaMap<LocalFieldId, Visibility>>;
|
||||||
|
|
||||||
|
@ -217,8 +216,14 @@ pub trait DefDatabase: InternDatabase + ExpandDatabase + Upcast<dyn ExpandDataba
|
||||||
#[salsa::invoke(visibility::const_visibility_query)]
|
#[salsa::invoke(visibility::const_visibility_query)]
|
||||||
fn const_visibility(&self, def: ConstId) -> Visibility;
|
fn const_visibility(&self, def: ConstId) -> Visibility;
|
||||||
|
|
||||||
|
// endregion:visibilities
|
||||||
|
|
||||||
|
#[salsa::invoke(LangItems::crate_lang_items_query)]
|
||||||
|
fn crate_lang_items(&self, krate: CrateId) -> Arc<LangItems>;
|
||||||
|
|
||||||
#[salsa::transparent]
|
#[salsa::transparent]
|
||||||
fn crate_limits(&self, crate_id: CrateId) -> CrateLimits;
|
fn crate_limits(&self, crate_id: CrateId) -> CrateLimits;
|
||||||
|
|
||||||
#[salsa::transparent]
|
#[salsa::transparent]
|
||||||
fn recursion_limit(&self, crate_id: CrateId) -> u32;
|
fn recursion_limit(&self, crate_id: CrateId) -> u32;
|
||||||
|
|
||||||
|
|
|
@ -81,7 +81,7 @@ fn find_path_inner(
|
||||||
}
|
}
|
||||||
|
|
||||||
let def_map = from.def_map(db);
|
let def_map = from.def_map(db);
|
||||||
let crate_root = def_map.crate_root(db);
|
let crate_root = def_map.crate_root();
|
||||||
// - if the item is a module, jump straight to module search
|
// - if the item is a module, jump straight to module search
|
||||||
if let ItemInNs::Types(ModuleDefId::ModuleId(module_id)) = item {
|
if let ItemInNs::Types(ModuleDefId::ModuleId(module_id)) = item {
|
||||||
let mut visited_modules = FxHashSet::default();
|
let mut visited_modules = FxHashSet::default();
|
||||||
|
@ -454,7 +454,7 @@ fn find_local_import_locations(
|
||||||
worklist.push(ancestor);
|
worklist.push(ancestor);
|
||||||
}
|
}
|
||||||
|
|
||||||
let def_map = def_map.crate_root(db).def_map(db);
|
let def_map = def_map.crate_root().def_map(db);
|
||||||
|
|
||||||
let mut seen: FxHashSet<_> = FxHashSet::default();
|
let mut seen: FxHashSet<_> = FxHashSet::default();
|
||||||
|
|
||||||
|
|
|
@ -11,8 +11,8 @@ use rustc_hash::{FxHashSet, FxHasher};
|
||||||
use triomphe::Arc;
|
use triomphe::Arc;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
db::DefDatabase, item_scope::ItemInNs, visibility::Visibility, AssocItemId, ModuleDefId,
|
db::DefDatabase, item_scope::ItemInNs, nameres::DefMap, visibility::Visibility, AssocItemId,
|
||||||
ModuleId, TraitId,
|
ModuleDefId, ModuleId, TraitId,
|
||||||
};
|
};
|
||||||
|
|
||||||
type FxIndexMap<K, V> = IndexMap<K, V, BuildHasherDefault<FxHasher>>;
|
type FxIndexMap<K, V> = IndexMap<K, V, BuildHasherDefault<FxHasher>>;
|
||||||
|
@ -183,7 +183,7 @@ fn collect_import_map(db: &dyn DefDatabase, krate: CrateId) -> ImportMap {
|
||||||
|
|
||||||
// We look only into modules that are public(ly reexported), starting with the crate root.
|
// We look only into modules that are public(ly reexported), starting with the crate root.
|
||||||
let empty = ImportPath { segments: vec![] };
|
let empty = ImportPath { segments: vec![] };
|
||||||
let root = def_map.module_id(def_map.root());
|
let root = def_map.module_id(DefMap::ROOT);
|
||||||
let mut worklist = vec![(root, empty)];
|
let mut worklist = vec![(root, empty)];
|
||||||
while let Some((module, mod_path)) = worklist.pop() {
|
while let Some((module, mod_path)) = worklist.pop() {
|
||||||
let ext_def_map;
|
let ext_def_map;
|
||||||
|
|
|
@ -35,7 +35,7 @@ use tt::token_id::{Subtree, TokenId};
|
||||||
use crate::{
|
use crate::{
|
||||||
db::DefDatabase,
|
db::DefDatabase,
|
||||||
macro_id_to_def_id,
|
macro_id_to_def_id,
|
||||||
nameres::{MacroSubNs, ModuleSource},
|
nameres::{DefMap, MacroSubNs, ModuleSource},
|
||||||
resolver::HasResolver,
|
resolver::HasResolver,
|
||||||
src::HasSource,
|
src::HasSource,
|
||||||
test_db::TestDB,
|
test_db::TestDB,
|
||||||
|
@ -61,7 +61,7 @@ pub fn identity_when_valid(_attr: TokenStream, item: TokenStream) -> TokenStream
|
||||||
let db = TestDB::with_files_extra_proc_macros(ra_fixture, extra_proc_macros);
|
let db = TestDB::with_files_extra_proc_macros(ra_fixture, extra_proc_macros);
|
||||||
let krate = db.crate_graph().iter().next().unwrap();
|
let krate = db.crate_graph().iter().next().unwrap();
|
||||||
let def_map = db.crate_def_map(krate);
|
let def_map = db.crate_def_map(krate);
|
||||||
let local_id = def_map.root();
|
let local_id = DefMap::ROOT;
|
||||||
let module = def_map.module_id(local_id);
|
let module = def_map.module_id(local_id);
|
||||||
let resolver = module.resolver(&db);
|
let resolver = module.resolver(&db);
|
||||||
let source = def_map[local_id].definition_source(&db);
|
let source = def_map[local_id].definition_source(&db);
|
||||||
|
|
|
@ -94,7 +94,6 @@ use crate::{
|
||||||
pub struct DefMap {
|
pub struct DefMap {
|
||||||
_c: Count<Self>,
|
_c: Count<Self>,
|
||||||
block: Option<BlockInfo>,
|
block: Option<BlockInfo>,
|
||||||
root: LocalModuleId,
|
|
||||||
modules: Arena<ModuleData>,
|
modules: Arena<ModuleData>,
|
||||||
krate: CrateId,
|
krate: CrateId,
|
||||||
/// The prelude module for this crate. This either comes from an import
|
/// The prelude module for this crate. This either comes from an import
|
||||||
|
@ -104,20 +103,29 @@ pub struct DefMap {
|
||||||
/// but that attribute is nightly and when used in a block, it affects resolution globally
|
/// but that attribute is nightly and when used in a block, it affects resolution globally
|
||||||
/// so we aren't handling this correctly anyways).
|
/// so we aren't handling this correctly anyways).
|
||||||
prelude: Option<ModuleId>,
|
prelude: Option<ModuleId>,
|
||||||
/// The extern prelude is only populated for non-block DefMaps
|
|
||||||
extern_prelude: FxHashMap<Name, ModuleId>,
|
|
||||||
/// `macro_use` prelude that contains macros from `#[macro_use]`'d external crates. Note that
|
/// `macro_use` prelude that contains macros from `#[macro_use]`'d external crates. Note that
|
||||||
/// this contains all kinds of macro, not just `macro_rules!` macro.
|
/// this contains all kinds of macro, not just `macro_rules!` macro.
|
||||||
macro_use_prelude: FxHashMap<Name, MacroId>,
|
macro_use_prelude: FxHashMap<Name, MacroId>,
|
||||||
|
|
||||||
|
/// Tracks which custom derives are in scope for an item, to allow resolution of derive helper
|
||||||
|
/// attributes.
|
||||||
|
derive_helpers_in_scope: FxHashMap<AstId<ast::Item>, Vec<(Name, MacroId, MacroCallId)>>,
|
||||||
|
|
||||||
|
diagnostics: Vec<DefDiagnostic>,
|
||||||
|
|
||||||
|
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>,
|
||||||
|
|
||||||
/// Side table for resolving derive helpers.
|
/// Side table for resolving derive helpers.
|
||||||
exported_derives: FxHashMap<MacroDefId, Box<[Name]>>,
|
exported_derives: FxHashMap<MacroDefId, Box<[Name]>>,
|
||||||
fn_proc_macro_mapping: FxHashMap<FunctionId, ProcMacroId>,
|
fn_proc_macro_mapping: FxHashMap<FunctionId, ProcMacroId>,
|
||||||
/// The error that occurred when failing to load the proc-macro dll.
|
/// The error that occurred when failing to load the proc-macro dll.
|
||||||
proc_macro_loading_error: Option<Box<str>>,
|
proc_macro_loading_error: Option<Box<str>>,
|
||||||
/// Tracks which custom derives are in scope for an item, to allow resolution of derive helper
|
|
||||||
/// attributes.
|
|
||||||
derive_helpers_in_scope: FxHashMap<AstId<ast::Item>, Vec<(Name, MacroId, MacroCallId)>>,
|
|
||||||
|
|
||||||
/// Custom attributes registered with `#![register_attr]`.
|
/// Custom attributes registered with `#![register_attr]`.
|
||||||
registered_attrs: Vec<SmolStr>,
|
registered_attrs: Vec<SmolStr>,
|
||||||
|
@ -132,7 +140,31 @@ pub struct DefMap {
|
||||||
|
|
||||||
edition: Edition,
|
edition: Edition,
|
||||||
recursion_limit: Option<u32>,
|
recursion_limit: Option<u32>,
|
||||||
diagnostics: Vec<DefDiagnostic>,
|
}
|
||||||
|
|
||||||
|
impl DefMapCrateData {
|
||||||
|
fn shrink_to_fit(&mut self) {
|
||||||
|
let Self {
|
||||||
|
extern_prelude,
|
||||||
|
exported_derives,
|
||||||
|
fn_proc_macro_mapping,
|
||||||
|
registered_attrs,
|
||||||
|
registered_tools,
|
||||||
|
unstable_features,
|
||||||
|
proc_macro_loading_error: _,
|
||||||
|
rustc_coherence_is_core: _,
|
||||||
|
no_core: _,
|
||||||
|
no_std: _,
|
||||||
|
edition: _,
|
||||||
|
recursion_limit: _,
|
||||||
|
} = self;
|
||||||
|
extern_prelude.shrink_to_fit();
|
||||||
|
exported_derives.shrink_to_fit();
|
||||||
|
fn_proc_macro_mapping.shrink_to_fit();
|
||||||
|
registered_attrs.shrink_to_fit();
|
||||||
|
registered_tools.shrink_to_fit();
|
||||||
|
unstable_features.shrink_to_fit();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// For `DefMap`s computed for a block expression, this stores its location in the parent map.
|
/// For `DefMap`s computed for a block expression, this stores its location in the parent map.
|
||||||
|
@ -141,7 +173,23 @@ struct BlockInfo {
|
||||||
/// The `BlockId` this `DefMap` was created from.
|
/// The `BlockId` this `DefMap` was created from.
|
||||||
block: BlockId,
|
block: BlockId,
|
||||||
/// The containing module.
|
/// The containing module.
|
||||||
parent: ModuleId,
|
parent: BlockRelativeModuleId,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
|
||||||
|
struct BlockRelativeModuleId {
|
||||||
|
block: Option<BlockId>,
|
||||||
|
local_id: LocalModuleId,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BlockRelativeModuleId {
|
||||||
|
fn def_map(self, db: &dyn DefDatabase, krate: CrateId) -> Arc<DefMap> {
|
||||||
|
self.into_module(krate).def_map(db)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn into_module(self, krate: CrateId) -> ModuleId {
|
||||||
|
ModuleId { krate, block: self.block, local_id: self.local_id }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::ops::Index<LocalModuleId> for DefMap {
|
impl std::ops::Index<LocalModuleId> for DefMap {
|
||||||
|
@ -231,6 +279,8 @@ pub struct ModuleData {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DefMap {
|
impl DefMap {
|
||||||
|
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> {
|
pub(crate) fn crate_def_map_query(db: &dyn DefDatabase, krate: CrateId) -> Arc<DefMap> {
|
||||||
let _p = profile::span("crate_def_map_query").detail(|| {
|
let _p = profile::span("crate_def_map_query").detail(|| {
|
||||||
db.crate_graph()[krate].display_name.as_deref().unwrap_or_default().to_string()
|
db.crate_graph()[krate].display_name.as_deref().unwrap_or_default().to_string()
|
||||||
|
@ -265,8 +315,15 @@ impl DefMap {
|
||||||
let module_data =
|
let module_data =
|
||||||
ModuleData::new(ModuleOrigin::BlockExpr { block: block.ast_id }, visibility);
|
ModuleData::new(ModuleOrigin::BlockExpr { block: block.ast_id }, visibility);
|
||||||
|
|
||||||
let mut def_map = DefMap::empty(krate, parent_map.edition, module_data);
|
let mut def_map = DefMap::empty(krate, parent_map.data.edition, module_data);
|
||||||
def_map.block = Some(BlockInfo { block: block_id, parent: block.module });
|
def_map.data = parent_map.data.clone();
|
||||||
|
def_map.block = Some(BlockInfo {
|
||||||
|
block: block_id,
|
||||||
|
parent: BlockRelativeModuleId {
|
||||||
|
block: block.module.block,
|
||||||
|
local_id: block.module.local_id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
let def_map = collector::collect_defs(db, def_map, tree_id);
|
let def_map = collector::collect_defs(db, def_map, tree_id);
|
||||||
Arc::new(def_map)
|
Arc::new(def_map)
|
||||||
|
@ -275,29 +332,31 @@ impl DefMap {
|
||||||
fn empty(krate: CrateId, edition: Edition, module_data: ModuleData) -> DefMap {
|
fn empty(krate: CrateId, edition: Edition, module_data: ModuleData) -> DefMap {
|
||||||
let mut modules: Arena<ModuleData> = Arena::default();
|
let mut modules: Arena<ModuleData> = Arena::default();
|
||||||
let root = modules.alloc(module_data);
|
let root = modules.alloc(module_data);
|
||||||
|
assert_eq!(root, Self::ROOT);
|
||||||
|
|
||||||
DefMap {
|
DefMap {
|
||||||
_c: Count::new(),
|
_c: Count::new(),
|
||||||
block: None,
|
block: None,
|
||||||
|
modules,
|
||||||
krate,
|
krate,
|
||||||
edition,
|
prelude: None,
|
||||||
recursion_limit: None,
|
|
||||||
extern_prelude: FxHashMap::default(),
|
|
||||||
macro_use_prelude: FxHashMap::default(),
|
macro_use_prelude: FxHashMap::default(),
|
||||||
|
derive_helpers_in_scope: FxHashMap::default(),
|
||||||
|
diagnostics: Vec::new(),
|
||||||
|
data: Arc::new(DefMapCrateData {
|
||||||
|
extern_prelude: FxHashMap::default(),
|
||||||
exported_derives: FxHashMap::default(),
|
exported_derives: FxHashMap::default(),
|
||||||
fn_proc_macro_mapping: FxHashMap::default(),
|
fn_proc_macro_mapping: FxHashMap::default(),
|
||||||
proc_macro_loading_error: None,
|
proc_macro_loading_error: None,
|
||||||
derive_helpers_in_scope: FxHashMap::default(),
|
|
||||||
prelude: None,
|
|
||||||
root,
|
|
||||||
modules,
|
|
||||||
registered_attrs: Vec::new(),
|
registered_attrs: Vec::new(),
|
||||||
registered_tools: Vec::new(),
|
registered_tools: Vec::new(),
|
||||||
unstable_features: FxHashSet::default(),
|
unstable_features: FxHashSet::default(),
|
||||||
diagnostics: Vec::new(),
|
|
||||||
rustc_coherence_is_core: false,
|
rustc_coherence_is_core: false,
|
||||||
no_core: false,
|
no_core: false,
|
||||||
no_std: false,
|
no_std: false,
|
||||||
|
edition,
|
||||||
|
recursion_limit: None,
|
||||||
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -320,35 +379,31 @@ impl DefMap {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn registered_tools(&self) -> &[SmolStr] {
|
pub fn registered_tools(&self) -> &[SmolStr] {
|
||||||
&self.registered_tools
|
&self.data.registered_tools
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn registered_attrs(&self) -> &[SmolStr] {
|
pub fn registered_attrs(&self) -> &[SmolStr] {
|
||||||
&self.registered_attrs
|
&self.data.registered_attrs
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_unstable_feature_enabled(&self, feature: &str) -> bool {
|
pub fn is_unstable_feature_enabled(&self, feature: &str) -> bool {
|
||||||
self.unstable_features.contains(feature)
|
self.data.unstable_features.contains(feature)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_rustc_coherence_is_core(&self) -> bool {
|
pub fn is_rustc_coherence_is_core(&self) -> bool {
|
||||||
self.rustc_coherence_is_core
|
self.data.rustc_coherence_is_core
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_no_std(&self) -> bool {
|
pub fn is_no_std(&self) -> bool {
|
||||||
self.no_std || self.no_core
|
self.data.no_std || self.data.no_core
|
||||||
}
|
|
||||||
|
|
||||||
pub fn root(&self) -> LocalModuleId {
|
|
||||||
self.root
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fn_as_proc_macro(&self, id: FunctionId) -> Option<ProcMacroId> {
|
pub fn fn_as_proc_macro(&self, id: FunctionId) -> Option<ProcMacroId> {
|
||||||
self.fn_proc_macro_mapping.get(&id).copied()
|
self.data.fn_proc_macro_mapping.get(&id).copied()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn proc_macro_loading_error(&self) -> Option<&str> {
|
pub fn proc_macro_loading_error(&self) -> Option<&str> {
|
||||||
self.proc_macro_loading_error.as_deref()
|
self.data.proc_macro_loading_error.as_deref()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn krate(&self) -> CrateId {
|
pub fn krate(&self) -> CrateId {
|
||||||
|
@ -364,7 +419,7 @@ impl DefMap {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn extern_prelude(&self) -> impl Iterator<Item = (&Name, ModuleId)> + '_ {
|
pub(crate) fn extern_prelude(&self) -> impl Iterator<Item = (&Name, ModuleId)> + '_ {
|
||||||
self.extern_prelude.iter().map(|(name, def)| (name, *def))
|
self.data.extern_prelude.iter().map(|(name, def)| (name, *def))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn macro_use_prelude(&self) -> impl Iterator<Item = (&Name, MacroId)> + '_ {
|
pub(crate) fn macro_use_prelude(&self) -> impl Iterator<Item = (&Name, MacroId)> + '_ {
|
||||||
|
@ -376,15 +431,8 @@ impl DefMap {
|
||||||
ModuleId { krate: self.krate, local_id, block }
|
ModuleId { krate: self.krate, local_id, block }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn crate_root(&self, db: &dyn DefDatabase) -> ModuleId {
|
pub(crate) fn crate_root(&self) -> ModuleId {
|
||||||
self.with_ancestor_maps(db, self.root, &mut |def_map, _module| {
|
ModuleId { krate: self.krate, block: None, local_id: DefMap::ROOT }
|
||||||
if def_map.block.is_none() {
|
|
||||||
Some(def_map.module_id(def_map.root))
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.expect("DefMap chain without root")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn resolve_path(
|
pub(crate) fn resolve_path(
|
||||||
|
@ -439,7 +487,7 @@ impl DefMap {
|
||||||
}
|
}
|
||||||
let mut block = self.block;
|
let mut block = self.block;
|
||||||
while let Some(block_info) = block {
|
while let Some(block_info) = block {
|
||||||
let parent = block_info.parent.def_map(db);
|
let parent = block_info.parent.def_map(db, self.krate);
|
||||||
if let Some(it) = f(&parent, block_info.parent.local_id) {
|
if let Some(it) = f(&parent, block_info.parent.local_id) {
|
||||||
return Some(it);
|
return Some(it);
|
||||||
}
|
}
|
||||||
|
@ -452,7 +500,8 @@ impl DefMap {
|
||||||
/// If this `DefMap` is for a block expression, returns the module containing the block (which
|
/// If this `DefMap` is for a block expression, returns the module containing the block (which
|
||||||
/// might again be a block, or a module inside a block).
|
/// might again be a block, or a module inside a block).
|
||||||
pub fn parent(&self) -> Option<ModuleId> {
|
pub fn parent(&self) -> Option<ModuleId> {
|
||||||
Some(self.block?.parent)
|
let BlockRelativeModuleId { block, local_id } = self.block?.parent;
|
||||||
|
Some(ModuleId { krate: self.krate, block, local_id })
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the module containing `local_mod`, either the parent `mod`, or the module (or block) containing
|
/// Returns the module containing `local_mod`, either the parent `mod`, or the module (or block) containing
|
||||||
|
@ -460,7 +509,13 @@ impl DefMap {
|
||||||
pub fn containing_module(&self, local_mod: LocalModuleId) -> Option<ModuleId> {
|
pub fn containing_module(&self, local_mod: LocalModuleId) -> Option<ModuleId> {
|
||||||
match self[local_mod].parent {
|
match self[local_mod].parent {
|
||||||
Some(parent) => Some(self.module_id(parent)),
|
Some(parent) => Some(self.module_id(parent)),
|
||||||
None => self.block.map(|block| block.parent),
|
None => {
|
||||||
|
self.block.map(
|
||||||
|
|BlockInfo { parent: BlockRelativeModuleId { block, local_id }, .. }| {
|
||||||
|
ModuleId { krate: self.krate, block, local_id }
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -471,12 +526,12 @@ impl DefMap {
|
||||||
let mut arc;
|
let mut arc;
|
||||||
let mut current_map = self;
|
let mut current_map = self;
|
||||||
while let Some(block) = current_map.block {
|
while let Some(block) = current_map.block {
|
||||||
go(&mut buf, db, current_map, "block scope", current_map.root);
|
go(&mut buf, db, current_map, "block scope", Self::ROOT);
|
||||||
buf.push('\n');
|
buf.push('\n');
|
||||||
arc = block.parent.def_map(db);
|
arc = block.parent.def_map(db, self.krate);
|
||||||
current_map = &arc;
|
current_map = &arc;
|
||||||
}
|
}
|
||||||
go(&mut buf, db, current_map, "crate", current_map.root);
|
go(&mut buf, db, current_map, "crate", Self::ROOT);
|
||||||
return buf;
|
return buf;
|
||||||
|
|
||||||
fn go(
|
fn go(
|
||||||
|
@ -506,7 +561,7 @@ impl DefMap {
|
||||||
let mut current_map = self;
|
let mut current_map = self;
|
||||||
while let Some(block) = current_map.block {
|
while let Some(block) = current_map.block {
|
||||||
format_to!(buf, "{:?} in {:?}\n", block.block, block.parent);
|
format_to!(buf, "{:?} in {:?}\n", block.block, block.parent);
|
||||||
arc = block.parent.def_map(db);
|
arc = block.parent.def_map(db, self.krate);
|
||||||
current_map = &arc;
|
current_map = &arc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -518,38 +573,20 @@ impl DefMap {
|
||||||
// Exhaustive match to require handling new fields.
|
// Exhaustive match to require handling new fields.
|
||||||
let Self {
|
let Self {
|
||||||
_c: _,
|
_c: _,
|
||||||
exported_derives,
|
|
||||||
extern_prelude,
|
|
||||||
macro_use_prelude,
|
macro_use_prelude,
|
||||||
diagnostics,
|
diagnostics,
|
||||||
modules,
|
modules,
|
||||||
registered_attrs,
|
|
||||||
registered_tools,
|
|
||||||
fn_proc_macro_mapping,
|
|
||||||
derive_helpers_in_scope,
|
derive_helpers_in_scope,
|
||||||
unstable_features,
|
|
||||||
proc_macro_loading_error: _,
|
|
||||||
block: _,
|
block: _,
|
||||||
edition: _,
|
|
||||||
recursion_limit: _,
|
|
||||||
krate: _,
|
krate: _,
|
||||||
prelude: _,
|
prelude: _,
|
||||||
root: _,
|
data: _,
|
||||||
rustc_coherence_is_core: _,
|
|
||||||
no_core: _,
|
|
||||||
no_std: _,
|
|
||||||
} = self;
|
} = self;
|
||||||
|
|
||||||
extern_prelude.shrink_to_fit();
|
|
||||||
macro_use_prelude.shrink_to_fit();
|
macro_use_prelude.shrink_to_fit();
|
||||||
exported_derives.shrink_to_fit();
|
|
||||||
diagnostics.shrink_to_fit();
|
diagnostics.shrink_to_fit();
|
||||||
modules.shrink_to_fit();
|
modules.shrink_to_fit();
|
||||||
registered_attrs.shrink_to_fit();
|
|
||||||
registered_tools.shrink_to_fit();
|
|
||||||
fn_proc_macro_mapping.shrink_to_fit();
|
|
||||||
derive_helpers_in_scope.shrink_to_fit();
|
derive_helpers_in_scope.shrink_to_fit();
|
||||||
unstable_features.shrink_to_fit();
|
|
||||||
for (_, module) in modules.iter_mut() {
|
for (_, module) in modules.iter_mut() {
|
||||||
module.children.shrink_to_fit();
|
module.children.shrink_to_fit();
|
||||||
module.scope.shrink_to_fit();
|
module.scope.shrink_to_fit();
|
||||||
|
@ -562,7 +599,7 @@ impl DefMap {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn recursion_limit(&self) -> Option<u32> {
|
pub fn recursion_limit(&self) -> Option<u32> {
|
||||||
self.recursion_limit
|
self.data.recursion_limit
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -78,7 +78,7 @@ impl DefMap {
|
||||||
let name = name.to_smol_str();
|
let name = name.to_smol_str();
|
||||||
let pred = |n: &_| *n == name;
|
let pred = |n: &_| *n == name;
|
||||||
|
|
||||||
let registered = self.registered_tools.iter().map(SmolStr::as_str);
|
let registered = self.data.registered_tools.iter().map(SmolStr::as_str);
|
||||||
let is_tool = TOOL_MODULES.iter().copied().chain(registered).any(pred);
|
let is_tool = TOOL_MODULES.iter().copied().chain(registered).any(pred);
|
||||||
// FIXME: tool modules can be shadowed by actual modules
|
// FIXME: tool modules can be shadowed by actual modules
|
||||||
if is_tool {
|
if is_tool {
|
||||||
|
@ -86,7 +86,7 @@ impl DefMap {
|
||||||
}
|
}
|
||||||
|
|
||||||
if segments.len() == 1 {
|
if segments.len() == 1 {
|
||||||
let mut registered = self.registered_attrs.iter().map(SmolStr::as_str);
|
let mut registered = self.data.registered_attrs.iter().map(SmolStr::as_str);
|
||||||
let is_inert = find_builtin_attr_idx(&name).is_some() || registered.any(pred);
|
let is_inert = find_builtin_attr_idx(&name).is_some() || registered.any(pred);
|
||||||
return is_inert;
|
return is_inert;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
use std::{iter, mem};
|
use std::{iter, mem};
|
||||||
|
|
||||||
use base_db::{CrateId, Edition, FileId};
|
use base_db::{CrateId, Dependency, Edition, FileId};
|
||||||
use cfg::{CfgExpr, CfgOptions};
|
use cfg::{CfgExpr, CfgOptions};
|
||||||
use either::Either;
|
use either::Either;
|
||||||
use hir_expand::{
|
use hir_expand::{
|
||||||
|
@ -62,7 +62,7 @@ static GLOB_RECURSION_LIMIT: Limit = Limit::new(100);
|
||||||
static EXPANSION_DEPTH_LIMIT: Limit = Limit::new(128);
|
static EXPANSION_DEPTH_LIMIT: Limit = Limit::new(128);
|
||||||
static FIXED_POINT_LIMIT: Limit = Limit::new(8192);
|
static FIXED_POINT_LIMIT: Limit = Limit::new(8192);
|
||||||
|
|
||||||
pub(super) fn collect_defs(db: &dyn DefDatabase, mut def_map: DefMap, tree_id: TreeId) -> DefMap {
|
pub(super) fn collect_defs(db: &dyn DefDatabase, def_map: DefMap, tree_id: TreeId) -> DefMap {
|
||||||
let crate_graph = db.crate_graph();
|
let crate_graph = db.crate_graph();
|
||||||
|
|
||||||
let mut deps = FxHashMap::default();
|
let mut deps = FxHashMap::default();
|
||||||
|
@ -70,14 +70,8 @@ pub(super) fn collect_defs(db: &dyn DefDatabase, mut def_map: DefMap, tree_id: T
|
||||||
let krate = &crate_graph[def_map.krate];
|
let krate = &crate_graph[def_map.krate];
|
||||||
for dep in &krate.dependencies {
|
for dep in &krate.dependencies {
|
||||||
tracing::debug!("crate dep {:?} -> {:?}", dep.name, dep.crate_id);
|
tracing::debug!("crate dep {:?} -> {:?}", dep.name, dep.crate_id);
|
||||||
let dep_def_map = db.crate_def_map(dep.crate_id);
|
|
||||||
let dep_root = dep_def_map.module_id(dep_def_map.root);
|
|
||||||
|
|
||||||
deps.insert(dep.as_name(), dep_root);
|
deps.insert(dep.as_name(), dep.clone());
|
||||||
|
|
||||||
if dep.is_prelude() && !tree_id.is_block() {
|
|
||||||
def_map.extern_prelude.insert(dep.as_name(), dep_root);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let cfg_options = &krate.cfg_options;
|
let cfg_options = &krate.cfg_options;
|
||||||
|
@ -86,7 +80,7 @@ pub(super) fn collect_defs(db: &dyn DefDatabase, mut def_map: DefMap, tree_id: T
|
||||||
let proc_macros = if is_proc_macro {
|
let proc_macros = if is_proc_macro {
|
||||||
match db.proc_macros().get(&def_map.krate) {
|
match db.proc_macros().get(&def_map.krate) {
|
||||||
Some(Ok(proc_macros)) => {
|
Some(Ok(proc_macros)) => {
|
||||||
proc_macros
|
Ok(proc_macros
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.map(|(idx, it)| {
|
.map(|(idx, it)| {
|
||||||
|
@ -95,20 +89,13 @@ pub(super) fn collect_defs(db: &dyn DefDatabase, mut def_map: DefMap, tree_id: T
|
||||||
tt::Ident { text: it.name.clone(), span: tt::TokenId::unspecified() };
|
tt::Ident { text: it.name.clone(), span: tt::TokenId::unspecified() };
|
||||||
(name.as_name(), ProcMacroExpander::new(base_db::ProcMacroId(idx as u32)))
|
(name.as_name(), ProcMacroExpander::new(base_db::ProcMacroId(idx as u32)))
|
||||||
})
|
})
|
||||||
.collect()
|
.collect())
|
||||||
}
|
|
||||||
Some(Err(e)) => {
|
|
||||||
def_map.proc_macro_loading_error = Some(e.clone().into_boxed_str());
|
|
||||||
Vec::new()
|
|
||||||
}
|
|
||||||
None => {
|
|
||||||
def_map.proc_macro_loading_error =
|
|
||||||
Some("No proc-macros present for crate".to_owned().into_boxed_str());
|
|
||||||
Vec::new()
|
|
||||||
}
|
}
|
||||||
|
Some(Err(e)) => Err(e.clone().into_boxed_str()),
|
||||||
|
None => Err("No proc-macros present for crate".to_owned().into_boxed_str()),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
vec![]
|
Ok(vec![])
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut collector = DefCollector {
|
let mut collector = DefCollector {
|
||||||
|
@ -252,7 +239,7 @@ enum MacroDirectiveKind {
|
||||||
struct DefCollector<'a> {
|
struct DefCollector<'a> {
|
||||||
db: &'a dyn DefDatabase,
|
db: &'a dyn DefDatabase,
|
||||||
def_map: DefMap,
|
def_map: DefMap,
|
||||||
deps: FxHashMap<Name, ModuleId>,
|
deps: FxHashMap<Name, Dependency>,
|
||||||
glob_imports: FxHashMap<LocalModuleId, Vec<(LocalModuleId, Visibility)>>,
|
glob_imports: FxHashMap<LocalModuleId, Vec<(LocalModuleId, Visibility)>>,
|
||||||
unresolved_imports: Vec<ImportDirective>,
|
unresolved_imports: Vec<ImportDirective>,
|
||||||
indeterminate_imports: Vec<ImportDirective>,
|
indeterminate_imports: Vec<ImportDirective>,
|
||||||
|
@ -263,7 +250,7 @@ struct DefCollector<'a> {
|
||||||
/// built by the build system, and is the list of proc. macros we can actually expand. It is
|
/// built by the build system, and is the list of proc. macros we can actually expand. It is
|
||||||
/// empty when proc. macro support is disabled (in which case we still do name resolution for
|
/// empty when proc. macro support is disabled (in which case we still do name resolution for
|
||||||
/// them).
|
/// them).
|
||||||
proc_macros: Vec<(Name, ProcMacroExpander)>,
|
proc_macros: Result<Vec<(Name, ProcMacroExpander)>, Box<str>>,
|
||||||
is_proc_macro: bool,
|
is_proc_macro: bool,
|
||||||
from_glob_import: PerNsGlobImports,
|
from_glob_import: PerNsGlobImports,
|
||||||
/// If we fail to resolve an attribute on a `ModItem`, we fall back to ignoring the attribute.
|
/// If we fail to resolve an attribute on a `ModItem`, we fall back to ignoring the attribute.
|
||||||
|
@ -287,9 +274,23 @@ impl DefCollector<'_> {
|
||||||
|
|
||||||
let file_id = self.db.crate_graph()[self.def_map.krate].root_file_id;
|
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 item_tree = self.db.file_item_tree(file_id.into());
|
||||||
let module_id = self.def_map.root;
|
let module_id = DefMap::ROOT;
|
||||||
|
|
||||||
let attrs = item_tree.top_level_attrs(self.db, self.def_map.krate);
|
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();
|
||||||
|
|
||||||
|
if let Err(e) = &self.proc_macros {
|
||||||
|
crate_data.proc_macro_loading_error = Some(e.clone());
|
||||||
|
}
|
||||||
|
|
||||||
|
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 },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Process other crate-level attributes.
|
// Process other crate-level attributes.
|
||||||
for attr in &*attrs {
|
for attr in &*attrs {
|
||||||
|
@ -306,7 +307,7 @@ impl DefCollector<'_> {
|
||||||
if *attr_name == hir_expand::name![recursion_limit] {
|
if *attr_name == hir_expand::name![recursion_limit] {
|
||||||
if let Some(limit) = attr.string_value() {
|
if let Some(limit) = attr.string_value() {
|
||||||
if let Ok(limit) = limit.parse() {
|
if let Ok(limit) = limit.parse() {
|
||||||
self.def_map.recursion_limit = Some(limit);
|
crate_data.recursion_limit = Some(limit);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
|
@ -320,17 +321,17 @@ impl DefCollector<'_> {
|
||||||
}
|
}
|
||||||
|
|
||||||
if *attr_name == hir_expand::name![no_core] {
|
if *attr_name == hir_expand::name![no_core] {
|
||||||
self.def_map.no_core = true;
|
crate_data.no_core = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if *attr_name == hir_expand::name![no_std] {
|
if *attr_name == hir_expand::name![no_std] {
|
||||||
self.def_map.no_std = true;
|
crate_data.no_std = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if attr_name.as_text().as_deref() == Some("rustc_coherence_is_core") {
|
if attr_name.as_text().as_deref() == Some("rustc_coherence_is_core") {
|
||||||
self.def_map.rustc_coherence_is_core = true;
|
crate_data.rustc_coherence_is_core = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -344,7 +345,7 @@ impl DefCollector<'_> {
|
||||||
[name] => Some(name.to_smol_str()),
|
[name] => Some(name.to_smol_str()),
|
||||||
_ => None,
|
_ => None,
|
||||||
});
|
});
|
||||||
self.def_map.unstable_features.extend(features);
|
crate_data.unstable_features.extend(features);
|
||||||
}
|
}
|
||||||
|
|
||||||
let attr_is_register_like = *attr_name == hir_expand::name![register_attr]
|
let attr_is_register_like = *attr_name == hir_expand::name![register_attr]
|
||||||
|
@ -359,14 +360,15 @@ impl DefCollector<'_> {
|
||||||
};
|
};
|
||||||
|
|
||||||
if *attr_name == hir_expand::name![register_attr] {
|
if *attr_name == hir_expand::name![register_attr] {
|
||||||
self.def_map.registered_attrs.push(registered_name.to_smol_str());
|
crate_data.registered_attrs.push(registered_name.to_smol_str());
|
||||||
cov_mark::hit!(register_attr);
|
cov_mark::hit!(register_attr);
|
||||||
} else {
|
} else {
|
||||||
self.def_map.registered_tools.push(registered_name.to_smol_str());
|
crate_data.registered_tools.push(registered_name.to_smol_str());
|
||||||
cov_mark::hit!(register_tool);
|
cov_mark::hit!(register_tool);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
crate_data.shrink_to_fit();
|
||||||
self.inject_prelude();
|
self.inject_prelude();
|
||||||
|
|
||||||
ModCollector {
|
ModCollector {
|
||||||
|
@ -382,7 +384,7 @@ impl DefCollector<'_> {
|
||||||
|
|
||||||
fn seed_with_inner(&mut self, tree_id: TreeId) {
|
fn seed_with_inner(&mut self, tree_id: TreeId) {
|
||||||
let item_tree = tree_id.item_tree(self.db);
|
let item_tree = tree_id.item_tree(self.db);
|
||||||
let module_id = self.def_map.root;
|
let module_id = DefMap::ROOT;
|
||||||
|
|
||||||
let is_cfg_enabled = item_tree
|
let is_cfg_enabled = item_tree
|
||||||
.top_level_attrs(self.db, self.def_map.krate)
|
.top_level_attrs(self.db, self.def_map.krate)
|
||||||
|
@ -464,7 +466,7 @@ impl DefCollector<'_> {
|
||||||
// Additionally, while the proc macro entry points must be `pub`, they are not publicly
|
// Additionally, while the proc macro entry points must be `pub`, they are not publicly
|
||||||
// exported in type/value namespace. This function reduces the visibility of all items
|
// exported in type/value namespace. This function reduces the visibility of all items
|
||||||
// in the crate root that aren't proc macros.
|
// in the crate root that aren't proc macros.
|
||||||
let root = self.def_map.root;
|
let root = DefMap::ROOT;
|
||||||
let module_id = self.def_map.module_id(root);
|
let module_id = self.def_map.module_id(root);
|
||||||
let root = &mut self.def_map.modules[root];
|
let root = &mut self.def_map.modules[root];
|
||||||
root.scope.censor_non_proc_macros(module_id);
|
root.scope.censor_non_proc_macros(module_id);
|
||||||
|
@ -530,12 +532,12 @@ impl DefCollector<'_> {
|
||||||
fn inject_prelude(&mut self) {
|
fn inject_prelude(&mut self) {
|
||||||
// See compiler/rustc_builtin_macros/src/standard_library_imports.rs
|
// See compiler/rustc_builtin_macros/src/standard_library_imports.rs
|
||||||
|
|
||||||
if self.def_map.no_core {
|
if self.def_map.data.no_core {
|
||||||
// libcore does not get a prelude.
|
// libcore does not get a prelude.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let krate = if self.def_map.no_std {
|
let krate = if self.def_map.data.no_std {
|
||||||
name![core]
|
name![core]
|
||||||
} else {
|
} else {
|
||||||
let std = name![std];
|
let std = name![std];
|
||||||
|
@ -548,25 +550,20 @@ impl DefCollector<'_> {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let edition = match self.def_map.edition {
|
let edition = match self.def_map.data.edition {
|
||||||
Edition::Edition2015 => name![rust_2015],
|
Edition::Edition2015 => name![rust_2015],
|
||||||
Edition::Edition2018 => name![rust_2018],
|
Edition::Edition2018 => name![rust_2018],
|
||||||
Edition::Edition2021 => name![rust_2021],
|
Edition::Edition2021 => name![rust_2021],
|
||||||
};
|
};
|
||||||
|
|
||||||
let path_kind = match self.def_map.edition {
|
let path_kind = match self.def_map.data.edition {
|
||||||
Edition::Edition2015 => PathKind::Plain,
|
Edition::Edition2015 => PathKind::Plain,
|
||||||
_ => PathKind::Abs,
|
_ => PathKind::Abs,
|
||||||
};
|
};
|
||||||
let path = ModPath::from_segments(path_kind, [krate, name![prelude], edition]);
|
let path = ModPath::from_segments(path_kind, [krate, name![prelude], edition]);
|
||||||
|
|
||||||
let (per_ns, _) = self.def_map.resolve_path(
|
let (per_ns, _) =
|
||||||
self.db,
|
self.def_map.resolve_path(self.db, DefMap::ROOT, &path, BuiltinShadowMode::Other, None);
|
||||||
self.def_map.root,
|
|
||||||
&path,
|
|
||||||
BuiltinShadowMode::Other,
|
|
||||||
None,
|
|
||||||
);
|
|
||||||
|
|
||||||
match per_ns.types {
|
match per_ns.types {
|
||||||
Some((ModuleDefId::ModuleId(m), _)) => {
|
Some((ModuleDefId::ModuleId(m), _)) => {
|
||||||
|
@ -603,23 +600,29 @@ impl DefCollector<'_> {
|
||||||
def: ProcMacroDef,
|
def: ProcMacroDef,
|
||||||
id: ItemTreeId<item_tree::Function>,
|
id: ItemTreeId<item_tree::Function>,
|
||||||
fn_id: FunctionId,
|
fn_id: FunctionId,
|
||||||
module_id: ModuleId,
|
|
||||||
) {
|
) {
|
||||||
|
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 kind = def.kind.to_basedb_kind();
|
||||||
let (expander, kind) = match self.proc_macros.iter().find(|(n, _)| n == &def.name) {
|
let (expander, kind) =
|
||||||
Some(&(_, expander)) => (expander, kind),
|
match self.proc_macros.as_ref().map(|it| it.iter().find(|(n, _)| n == &def.name)) {
|
||||||
None => (ProcMacroExpander::dummy(), kind),
|
Ok(Some(&(_, expander))) => (expander, kind),
|
||||||
|
_ => (ProcMacroExpander::dummy(), kind),
|
||||||
};
|
};
|
||||||
|
|
||||||
let proc_macro_id =
|
let proc_macro_id =
|
||||||
ProcMacroLoc { container: module_id, id, expander, kind }.intern(self.db);
|
ProcMacroLoc { container: crate_root, id, expander, kind }.intern(self.db);
|
||||||
self.define_proc_macro(def.name.clone(), proc_macro_id);
|
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 {
|
if let ProcMacroKind::CustomDerive { helpers } = def.kind {
|
||||||
self.def_map
|
crate_data
|
||||||
.exported_derives
|
.exported_derives
|
||||||
.insert(macro_id_to_def_id(self.db, proc_macro_id.into()), helpers);
|
.insert(macro_id_to_def_id(self.db, proc_macro_id.into()), helpers);
|
||||||
}
|
}
|
||||||
self.def_map.fn_proc_macro_mapping.insert(fn_id, proc_macro_id);
|
crate_data.fn_proc_macro_mapping.insert(fn_id, proc_macro_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Define a macro with `macro_rules`.
|
/// Define a macro with `macro_rules`.
|
||||||
|
@ -661,7 +664,7 @@ impl DefCollector<'_> {
|
||||||
// In Rust, `#[macro_export]` macros are unconditionally visible at the
|
// In Rust, `#[macro_export]` macros are unconditionally visible at the
|
||||||
// crate root, even if the parent modules is **not** visible.
|
// crate root, even if the parent modules is **not** visible.
|
||||||
if export {
|
if export {
|
||||||
let module_id = self.def_map.root;
|
let module_id = DefMap::ROOT;
|
||||||
self.def_map.modules[module_id].scope.declare(macro_.into());
|
self.def_map.modules[module_id].scope.declare(macro_.into());
|
||||||
self.update(
|
self.update(
|
||||||
module_id,
|
module_id,
|
||||||
|
@ -712,7 +715,7 @@ impl DefCollector<'_> {
|
||||||
/// A proc macro is similar to normal macro scope, but it would not visible in legacy textual scoped.
|
/// A proc macro is similar to normal macro scope, but it would not visible in legacy textual scoped.
|
||||||
/// And unconditionally exported.
|
/// And unconditionally exported.
|
||||||
fn define_proc_macro(&mut self, name: Name, macro_: ProcMacroId) {
|
fn define_proc_macro(&mut self, name: Name, macro_: ProcMacroId) {
|
||||||
let module_id = self.def_map.root;
|
let module_id = DefMap::ROOT;
|
||||||
self.def_map.modules[module_id].scope.declare(macro_.into());
|
self.def_map.modules[module_id].scope.declare(macro_.into());
|
||||||
self.update(
|
self.update(
|
||||||
module_id,
|
module_id,
|
||||||
|
@ -732,7 +735,7 @@ impl DefCollector<'_> {
|
||||||
let def_map = self.db.crate_def_map(krate);
|
let def_map = self.db.crate_def_map(krate);
|
||||||
// `#[macro_use]` brings macros into macro_use prelude. Yes, even non-`macro_rules!`
|
// `#[macro_use]` brings macros into macro_use prelude. Yes, even non-`macro_rules!`
|
||||||
// macros.
|
// macros.
|
||||||
let root_scope = &def_map[def_map.root].scope;
|
let root_scope = &def_map[DefMap::ROOT].scope;
|
||||||
if let Some(names) = names {
|
if let Some(names) = names {
|
||||||
for name in names {
|
for name in names {
|
||||||
// FIXME: Report diagnostic on 404.
|
// FIXME: Report diagnostic on 404.
|
||||||
|
@ -778,7 +781,7 @@ impl DefCollector<'_> {
|
||||||
fn resolve_import(&self, module_id: LocalModuleId, import: &Import) -> PartialResolvedImport {
|
fn resolve_import(&self, module_id: LocalModuleId, import: &Import) -> PartialResolvedImport {
|
||||||
let _p = profile::span("resolve_import")
|
let _p = profile::span("resolve_import")
|
||||||
.detail(|| format!("{}", import.path.display(self.db.upcast())));
|
.detail(|| format!("{}", import.path.display(self.db.upcast())));
|
||||||
tracing::debug!("resolving import: {:?} ({:?})", import, self.def_map.edition);
|
tracing::debug!("resolving import: {:?} ({:?})", import, self.def_map.data.edition);
|
||||||
if import.is_extern_crate {
|
if import.is_extern_crate {
|
||||||
let name = import
|
let name = import
|
||||||
.path
|
.path
|
||||||
|
@ -831,16 +834,13 @@ impl DefCollector<'_> {
|
||||||
fn resolve_extern_crate(&self, name: &Name) -> Option<ModuleId> {
|
fn resolve_extern_crate(&self, name: &Name) -> Option<ModuleId> {
|
||||||
if *name == name!(self) {
|
if *name == name!(self) {
|
||||||
cov_mark::hit!(extern_crate_self_as);
|
cov_mark::hit!(extern_crate_self_as);
|
||||||
let root = match self.def_map.block {
|
Some(self.def_map.crate_root())
|
||||||
Some(_) => {
|
|
||||||
let def_map = self.def_map.crate_root(self.db).def_map(self.db);
|
|
||||||
def_map.module_id(def_map.root())
|
|
||||||
}
|
|
||||||
None => self.def_map.module_id(self.def_map.root()),
|
|
||||||
};
|
|
||||||
Some(root)
|
|
||||||
} else {
|
} else {
|
||||||
self.deps.get(name).copied()
|
self.deps.get(name).map(|dep| ModuleId {
|
||||||
|
krate: dep.crate_id,
|
||||||
|
block: None,
|
||||||
|
local_id: DefMap::ROOT,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -879,11 +879,14 @@ impl DefCollector<'_> {
|
||||||
// extern crates in the crate root are special-cased to insert entries into the extern prelude: rust-lang/rust#54658
|
// extern crates in the crate root are special-cased to insert entries into the extern prelude: rust-lang/rust#54658
|
||||||
if import.is_extern_crate
|
if import.is_extern_crate
|
||||||
&& self.def_map.block.is_none()
|
&& self.def_map.block.is_none()
|
||||||
&& module_id == self.def_map.root
|
&& module_id == DefMap::ROOT
|
||||||
{
|
{
|
||||||
if let (Some(ModuleDefId::ModuleId(def)), Some(name)) = (def.take_types(), name)
|
if let (Some(ModuleDefId::ModuleId(def)), Some(name)) = (def.take_types(), name)
|
||||||
{
|
{
|
||||||
self.def_map.extern_prelude.insert(name.clone(), def);
|
Arc::get_mut(&mut self.def_map.data)
|
||||||
|
.unwrap()
|
||||||
|
.extern_prelude
|
||||||
|
.insert(name.clone(), def);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1158,7 +1161,7 @@ impl DefCollector<'_> {
|
||||||
// Record its helper attributes.
|
// Record its helper attributes.
|
||||||
if def_id.krate != self.def_map.krate {
|
if def_id.krate != self.def_map.krate {
|
||||||
let def_map = self.db.crate_def_map(def_id.krate);
|
let def_map = self.db.crate_def_map(def_id.krate);
|
||||||
if let Some(helpers) = def_map.exported_derives.get(&def_id) {
|
if let Some(helpers) = def_map.data.exported_derives.get(&def_id) {
|
||||||
self.def_map
|
self.def_map
|
||||||
.derive_helpers_in_scope
|
.derive_helpers_in_scope
|
||||||
.entry(ast_id.ast_id.map(|it| it.upcast()))
|
.entry(ast_id.ast_id.map(|it| it.upcast()))
|
||||||
|
@ -1525,7 +1528,7 @@ impl ModCollector<'_, '_> {
|
||||||
|
|
||||||
fn collect(&mut self, items: &[ModItem], container: ItemContainerId) {
|
fn collect(&mut self, items: &[ModItem], container: ItemContainerId) {
|
||||||
let krate = self.def_collector.def_map.krate;
|
let krate = self.def_collector.def_map.krate;
|
||||||
let is_crate_root = self.module_id == self.def_collector.def_map.root;
|
let is_crate_root = self.module_id == DefMap::ROOT;
|
||||||
|
|
||||||
// Note: don't assert that inserted value is fresh: it's simply not true
|
// Note: don't assert that inserted value is fresh: it's simply not true
|
||||||
// for macros.
|
// for macros.
|
||||||
|
@ -1641,14 +1644,12 @@ impl ModCollector<'_, '_> {
|
||||||
FunctionLoc { container, id: ItemTreeId::new(self.tree_id, id) }.intern(db);
|
FunctionLoc { container, id: ItemTreeId::new(self.tree_id, id) }.intern(db);
|
||||||
|
|
||||||
let vis = resolve_vis(def_map, &self.item_tree[it.visibility]);
|
let vis = resolve_vis(def_map, &self.item_tree[it.visibility]);
|
||||||
if self.def_collector.is_proc_macro && self.module_id == def_map.root {
|
if self.def_collector.is_proc_macro && self.module_id == DefMap::ROOT {
|
||||||
if let Some(proc_macro) = attrs.parse_proc_macro_decl(&it.name) {
|
if let Some(proc_macro) = attrs.parse_proc_macro_decl(&it.name) {
|
||||||
let crate_root = def_map.module_id(def_map.root);
|
|
||||||
self.def_collector.export_proc_macro(
|
self.def_collector.export_proc_macro(
|
||||||
proc_macro,
|
proc_macro,
|
||||||
ItemTreeId::new(self.tree_id, id),
|
ItemTreeId::new(self.tree_id, id),
|
||||||
fn_id,
|
fn_id,
|
||||||
crate_root,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2169,12 +2170,14 @@ impl ModCollector<'_, '_> {
|
||||||
&self.item_tree[mac.visibility],
|
&self.item_tree[mac.visibility],
|
||||||
);
|
);
|
||||||
if let Some(helpers) = helpers_opt {
|
if let Some(helpers) = helpers_opt {
|
||||||
self.def_collector
|
if self.def_collector.def_map.block.is_none() {
|
||||||
.def_map
|
Arc::get_mut(&mut self.def_collector.def_map.data)
|
||||||
|
.unwrap()
|
||||||
.exported_derives
|
.exported_derives
|
||||||
.insert(macro_id_to_def_id(self.def_collector.db, macro_id.into()), helpers);
|
.insert(macro_id_to_def_id(self.def_collector.db, macro_id.into()), helpers);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn collect_macro_call(&mut self, mac: &MacroCall, container: ItemContainerId) {
|
fn collect_macro_call(&mut self, mac: &MacroCall, container: ItemContainerId) {
|
||||||
let ast_id = AstIdWithPath::new(self.file_id(), mac.ast_id, ModPath::clone(&mac.path));
|
let ast_id = AstIdWithPath::new(self.file_id(), mac.ast_id, ModPath::clone(&mac.path));
|
||||||
|
@ -2280,7 +2283,7 @@ mod tests {
|
||||||
unresolved_macros: Vec::new(),
|
unresolved_macros: Vec::new(),
|
||||||
mod_dirs: FxHashMap::default(),
|
mod_dirs: FxHashMap::default(),
|
||||||
cfg_options: &CfgOptions::default(),
|
cfg_options: &CfgOptions::default(),
|
||||||
proc_macros: Default::default(),
|
proc_macros: Ok(vec![]),
|
||||||
from_glob_import: Default::default(),
|
from_glob_import: Default::default(),
|
||||||
skip_attrs: Default::default(),
|
skip_attrs: Default::default(),
|
||||||
is_proc_macro: false,
|
is_proc_macro: false,
|
||||||
|
|
|
@ -20,7 +20,7 @@ use crate::{
|
||||||
path::{ModPath, PathKind},
|
path::{ModPath, PathKind},
|
||||||
per_ns::PerNs,
|
per_ns::PerNs,
|
||||||
visibility::{RawVisibility, Visibility},
|
visibility::{RawVisibility, Visibility},
|
||||||
AdtId, CrateId, EnumVariantId, LocalModuleId, ModuleDefId, ModuleId,
|
AdtId, CrateId, EnumVariantId, LocalModuleId, ModuleDefId,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
|
@ -74,17 +74,6 @@ impl PerNs {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DefMap {
|
impl DefMap {
|
||||||
pub(super) fn resolve_name_in_extern_prelude(
|
|
||||||
&self,
|
|
||||||
db: &dyn DefDatabase,
|
|
||||||
name: &Name,
|
|
||||||
) -> Option<ModuleId> {
|
|
||||||
match self.block {
|
|
||||||
Some(_) => self.crate_root(db).def_map(db).extern_prelude.get(name).copied(),
|
|
||||||
None => self.extern_prelude.get(name).copied(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn resolve_visibility(
|
pub(crate) fn resolve_visibility(
|
||||||
&self,
|
&self,
|
||||||
db: &dyn DefDatabase,
|
db: &dyn DefDatabase,
|
||||||
|
@ -121,7 +110,7 @@ impl DefMap {
|
||||||
// ...unless we're resolving visibility for an associated item in an impl.
|
// ...unless we're resolving visibility for an associated item in an impl.
|
||||||
if self.block_id() != m.block && !within_impl {
|
if self.block_id() != m.block && !within_impl {
|
||||||
cov_mark::hit!(adjust_vis_in_block_def_map);
|
cov_mark::hit!(adjust_vis_in_block_def_map);
|
||||||
vis = Visibility::Module(self.module_id(self.root()));
|
vis = Visibility::Module(self.module_id(Self::ROOT));
|
||||||
tracing::debug!("visibility {:?} points outside DefMap, adjusting to {:?}", m, vis);
|
tracing::debug!("visibility {:?} points outside DefMap, adjusting to {:?}", m, vis);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -173,7 +162,7 @@ impl DefMap {
|
||||||
match ¤t_map.block {
|
match ¤t_map.block {
|
||||||
Some(block) => {
|
Some(block) => {
|
||||||
original_module = block.parent.local_id;
|
original_module = block.parent.local_id;
|
||||||
arc = block.parent.def_map(db);
|
arc = block.parent.def_map(db, current_map.krate);
|
||||||
current_map = &*arc;
|
current_map = &*arc;
|
||||||
}
|
}
|
||||||
None => return result,
|
None => return result,
|
||||||
|
@ -204,21 +193,21 @@ impl DefMap {
|
||||||
PathKind::DollarCrate(krate) => {
|
PathKind::DollarCrate(krate) => {
|
||||||
if krate == self.krate {
|
if krate == self.krate {
|
||||||
cov_mark::hit!(macro_dollar_crate_self);
|
cov_mark::hit!(macro_dollar_crate_self);
|
||||||
PerNs::types(self.crate_root(db).into(), Visibility::Public)
|
PerNs::types(self.crate_root().into(), Visibility::Public)
|
||||||
} else {
|
} else {
|
||||||
let def_map = db.crate_def_map(krate);
|
let def_map = db.crate_def_map(krate);
|
||||||
let module = def_map.module_id(def_map.root);
|
let module = def_map.module_id(Self::ROOT);
|
||||||
cov_mark::hit!(macro_dollar_crate_other);
|
cov_mark::hit!(macro_dollar_crate_other);
|
||||||
PerNs::types(module.into(), Visibility::Public)
|
PerNs::types(module.into(), Visibility::Public)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PathKind::Crate => PerNs::types(self.crate_root(db).into(), Visibility::Public),
|
PathKind::Crate => PerNs::types(self.crate_root().into(), Visibility::Public),
|
||||||
// plain import or absolute path in 2015: crate-relative with
|
// plain import or absolute path in 2015: crate-relative with
|
||||||
// fallback to extern prelude (with the simplification in
|
// fallback to extern prelude (with the simplification in
|
||||||
// rust-lang/rust#57745)
|
// rust-lang/rust#57745)
|
||||||
// FIXME there must be a nicer way to write this condition
|
// FIXME there must be a nicer way to write this condition
|
||||||
PathKind::Plain | PathKind::Abs
|
PathKind::Plain | PathKind::Abs
|
||||||
if self.edition == Edition::Edition2015
|
if self.data.edition == Edition::Edition2015
|
||||||
&& (path.kind == PathKind::Abs || mode == ResolveMode::Import) =>
|
&& (path.kind == PathKind::Abs || mode == ResolveMode::Import) =>
|
||||||
{
|
{
|
||||||
let (_, segment) = match segments.next() {
|
let (_, segment) = match segments.next() {
|
||||||
|
@ -268,7 +257,10 @@ impl DefMap {
|
||||||
path.display(db.upcast()),
|
path.display(db.upcast()),
|
||||||
new_path.display(db.upcast())
|
new_path.display(db.upcast())
|
||||||
);
|
);
|
||||||
return block.parent.def_map(db).resolve_path_fp_with_macro(
|
return block
|
||||||
|
.parent
|
||||||
|
.def_map(db, self.krate)
|
||||||
|
.resolve_path_fp_with_macro(
|
||||||
db,
|
db,
|
||||||
mode,
|
mode,
|
||||||
block.parent.local_id,
|
block.parent.local_id,
|
||||||
|
@ -301,7 +293,7 @@ impl DefMap {
|
||||||
Some((_, segment)) => segment,
|
Some((_, segment)) => segment,
|
||||||
None => return ResolvePathResult::empty(ReachedFixedPoint::Yes),
|
None => return ResolvePathResult::empty(ReachedFixedPoint::Yes),
|
||||||
};
|
};
|
||||||
if let Some(&def) = self.extern_prelude.get(segment) {
|
if let Some(&def) = self.data.extern_prelude.get(segment) {
|
||||||
tracing::debug!("absolute path {:?} resolved to crate {:?}", path, def);
|
tracing::debug!("absolute path {:?} resolved to crate {:?}", path, def);
|
||||||
PerNs::types(def.into(), Visibility::Public)
|
PerNs::types(def.into(), Visibility::Public)
|
||||||
} else {
|
} else {
|
||||||
|
@ -450,7 +442,12 @@ impl DefMap {
|
||||||
};
|
};
|
||||||
|
|
||||||
let extern_prelude = || {
|
let extern_prelude = || {
|
||||||
self.extern_prelude
|
if self.block.is_some() {
|
||||||
|
// Don't resolve extern prelude in block `DefMap`s.
|
||||||
|
return PerNs::none();
|
||||||
|
}
|
||||||
|
self.data
|
||||||
|
.extern_prelude
|
||||||
.get(name)
|
.get(name)
|
||||||
.map_or(PerNs::none(), |&it| PerNs::types(it.into(), Visibility::Public))
|
.map_or(PerNs::none(), |&it| PerNs::types(it.into(), Visibility::Public))
|
||||||
};
|
};
|
||||||
|
@ -475,13 +472,20 @@ impl DefMap {
|
||||||
) -> PerNs {
|
) -> PerNs {
|
||||||
let from_crate_root = match self.block {
|
let from_crate_root = match self.block {
|
||||||
Some(_) => {
|
Some(_) => {
|
||||||
let def_map = self.crate_root(db).def_map(db);
|
let def_map = self.crate_root().def_map(db);
|
||||||
def_map[def_map.root].scope.get(name)
|
def_map[Self::ROOT].scope.get(name)
|
||||||
}
|
}
|
||||||
None => self[self.root].scope.get(name),
|
None => self[Self::ROOT].scope.get(name),
|
||||||
};
|
};
|
||||||
let from_extern_prelude = || {
|
let from_extern_prelude = || {
|
||||||
self.resolve_name_in_extern_prelude(db, name)
|
if self.block.is_some() {
|
||||||
|
// Don't resolve extern prelude in block `DefMap`s.
|
||||||
|
return PerNs::none();
|
||||||
|
}
|
||||||
|
self.data
|
||||||
|
.extern_prelude
|
||||||
|
.get(name)
|
||||||
|
.copied()
|
||||||
.map_or(PerNs::none(), |it| PerNs::types(it.into(), Visibility::Public))
|
.map_or(PerNs::none(), |it| PerNs::types(it.into(), Visibility::Public))
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -750,7 +750,7 @@ macro_rules! foo {
|
||||||
pub use core::clone::Clone;
|
pub use core::clone::Clone;
|
||||||
"#,
|
"#,
|
||||||
);
|
);
|
||||||
assert_eq!(map.modules[map.root].scope.impls().len(), 1);
|
assert_eq!(map.modules[DefMap::ROOT].scope.impls().len(), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -772,7 +772,7 @@ pub macro Copy {}
|
||||||
pub macro Clone {}
|
pub macro Clone {}
|
||||||
"#,
|
"#,
|
||||||
);
|
);
|
||||||
assert_eq!(map.modules[map.root].scope.impls().len(), 2);
|
assert_eq!(map.modules[DefMap::ROOT].scope.impls().len(), 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -815,7 +815,7 @@ pub macro derive($item:item) {}
|
||||||
pub macro Clone {}
|
pub macro Clone {}
|
||||||
"#,
|
"#,
|
||||||
);
|
);
|
||||||
assert_eq!(map.modules[map.root].scope.impls().len(), 1);
|
assert_eq!(map.modules[DefMap::ROOT].scope.impls().len(), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -1094,8 +1094,8 @@ pub fn derive_macro_2(_item: TokenStream) -> TokenStream {
|
||||||
let krate = db.crate_graph().iter().next().unwrap();
|
let krate = db.crate_graph().iter().next().unwrap();
|
||||||
let def_map = db.crate_def_map(krate);
|
let def_map = db.crate_def_map(krate);
|
||||||
|
|
||||||
assert_eq!(def_map.exported_derives.len(), 1);
|
assert_eq!(def_map.data.exported_derives.len(), 1);
|
||||||
match def_map.exported_derives.values().next() {
|
match def_map.data.exported_derives.values().next() {
|
||||||
Some(helpers) => match &**helpers {
|
Some(helpers) => match &**helpers {
|
||||||
[attr] => assert_eq!(attr.display(&db).to_string(), "helper_attr"),
|
[attr] => assert_eq!(attr.display(&db).to_string(), "helper_attr"),
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
|
@ -1286,7 +1286,7 @@ fn proc_attr(a: TokenStream, b: TokenStream) -> TokenStream { a }
|
||||||
let krate = db.crate_graph().iter().next().unwrap();
|
let krate = db.crate_graph().iter().next().unwrap();
|
||||||
let def_map = db.crate_def_map(krate);
|
let def_map = db.crate_def_map(krate);
|
||||||
|
|
||||||
let root_module = &def_map[def_map.root()].scope;
|
let root_module = &def_map[DefMap::ROOT].scope;
|
||||||
assert!(
|
assert!(
|
||||||
root_module.legacy_macros().count() == 0,
|
root_module.legacy_macros().count() == 0,
|
||||||
"`#[macro_use]` shouldn't bring macros into textual macro scope",
|
"`#[macro_use]` shouldn't bring macros into textual macro scope",
|
||||||
|
@ -1392,7 +1392,7 @@ macro_rules! derive { () => {} }
|
||||||
struct S;
|
struct S;
|
||||||
"#,
|
"#,
|
||||||
);
|
);
|
||||||
assert_eq!(map.modules[map.root].scope.impls().len(), 1);
|
assert_eq!(map.modules[DefMap::ROOT].scope.impls().len(), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
@ -586,8 +586,9 @@ impl Resolver {
|
||||||
}));
|
}));
|
||||||
if let Some(block) = expr_scopes.block(scope_id) {
|
if let Some(block) = expr_scopes.block(scope_id) {
|
||||||
let def_map = db.block_def_map(block);
|
let def_map = db.block_def_map(block);
|
||||||
let root = def_map.root();
|
resolver
|
||||||
resolver.scopes.push(Scope::BlockScope(ModuleItemMap { def_map, module_id: root }));
|
.scopes
|
||||||
|
.push(Scope::BlockScope(ModuleItemMap { def_map, module_id: DefMap::ROOT }));
|
||||||
// FIXME: This adds as many module scopes as there are blocks, but resolving in each
|
// FIXME: This adds as many module scopes as there are blocks, but resolving in each
|
||||||
// already traverses all parents, so this is O(n²). I think we could only store the
|
// already traverses all parents, so this is O(n²). I think we could only store the
|
||||||
// innermost module scope instead?
|
// innermost module scope instead?
|
||||||
|
@ -753,8 +754,7 @@ fn resolver_for_scope_(
|
||||||
for scope in scope_chain.into_iter().rev() {
|
for scope in scope_chain.into_iter().rev() {
|
||||||
if let Some(block) = scopes.block(scope) {
|
if let Some(block) = scopes.block(scope) {
|
||||||
let def_map = db.block_def_map(block);
|
let def_map = db.block_def_map(block);
|
||||||
let root = def_map.root();
|
r = r.push_block_scope(def_map, DefMap::ROOT);
|
||||||
r = r.push_block_scope(def_map, root);
|
|
||||||
// FIXME: This adds as many module scopes as there are blocks, but resolving in each
|
// FIXME: This adds as many module scopes as there are blocks, but resolving in each
|
||||||
// already traverses all parents, so this is O(n²). I think we could only store the
|
// already traverses all parents, so this is O(n²). I think we could only store the
|
||||||
// innermost module scope instead?
|
// innermost module scope instead?
|
||||||
|
|
|
@ -110,7 +110,7 @@ impl TestDB {
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
// FIXME: handle `mod` inside block expression
|
// FIXME: handle `mod` inside block expression
|
||||||
return def_map.module_id(def_map.root());
|
return def_map.module_id(DefMap::ROOT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -119,7 +119,7 @@ impl TestDB {
|
||||||
/// Finds the smallest/innermost module in `def_map` containing `position`.
|
/// Finds the smallest/innermost module in `def_map` containing `position`.
|
||||||
fn mod_at_position(&self, def_map: &DefMap, position: FilePosition) -> LocalModuleId {
|
fn mod_at_position(&self, def_map: &DefMap, position: FilePosition) -> LocalModuleId {
|
||||||
let mut size = None;
|
let mut size = None;
|
||||||
let mut res = def_map.root();
|
let mut res = DefMap::ROOT;
|
||||||
for (module, data) in def_map.modules() {
|
for (module, data) in def_map.modules() {
|
||||||
let src = data.definition_source(self);
|
let src = data.definition_source(self);
|
||||||
if src.file_id != position.file_id.into() {
|
if src.file_id != position.file_id.into() {
|
||||||
|
|
|
@ -13,6 +13,7 @@ use hir_def::{
|
||||||
generics::{TypeOrConstParamData, TypeParamProvenance},
|
generics::{TypeOrConstParamData, TypeParamProvenance},
|
||||||
item_scope::ItemInNs,
|
item_scope::ItemInNs,
|
||||||
lang_item::{LangItem, LangItemTarget},
|
lang_item::{LangItem, LangItemTarget},
|
||||||
|
nameres::DefMap,
|
||||||
path::{Path, PathKind},
|
path::{Path, PathKind},
|
||||||
type_ref::{TraitBoundModifier, TypeBound, TypeRef},
|
type_ref::{TraitBoundModifier, TypeBound, TypeRef},
|
||||||
visibility::Visibility,
|
visibility::Visibility,
|
||||||
|
@ -1488,7 +1489,7 @@ pub fn write_visibility(
|
||||||
Visibility::Public => write!(f, "pub "),
|
Visibility::Public => write!(f, "pub "),
|
||||||
Visibility::Module(vis_id) => {
|
Visibility::Module(vis_id) => {
|
||||||
let def_map = module_id.def_map(f.db.upcast());
|
let def_map = module_id.def_map(f.db.upcast());
|
||||||
let root_module_id = def_map.module_id(def_map.root());
|
let root_module_id = def_map.module_id(DefMap::ROOT);
|
||||||
if vis_id == module_id {
|
if vis_id == module_id {
|
||||||
// pub(self) or omitted
|
// pub(self) or omitted
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -548,7 +548,7 @@ impl HirDisplay for Module {
|
||||||
// FIXME: Module doesn't have visibility saved in data.
|
// FIXME: Module doesn't have visibility saved in data.
|
||||||
match self.name(f.db) {
|
match self.name(f.db) {
|
||||||
Some(name) => write!(f, "mod {}", name.display(f.db.upcast())),
|
Some(name) => write!(f, "mod {}", name.display(f.db.upcast())),
|
||||||
None if self.is_crate_root(f.db) => match self.krate(f.db).display_name(f.db) {
|
None if self.is_crate_root() => match self.krate(f.db).display_name(f.db) {
|
||||||
Some(name) => write!(f, "extern crate {name}"),
|
Some(name) => write!(f, "extern crate {name}"),
|
||||||
None => f.write_str("extern crate {unknown}"),
|
None => f.write_str("extern crate {unknown}"),
|
||||||
},
|
},
|
||||||
|
|
|
@ -118,7 +118,7 @@ pub use {
|
||||||
find_path::PrefixKind,
|
find_path::PrefixKind,
|
||||||
import_map,
|
import_map,
|
||||||
lang_item::LangItem,
|
lang_item::LangItem,
|
||||||
nameres::ModuleSource,
|
nameres::{DefMap, ModuleSource},
|
||||||
path::{ModPath, PathKind},
|
path::{ModPath, PathKind},
|
||||||
type_ref::{Mutability, TypeRef},
|
type_ref::{Mutability, TypeRef},
|
||||||
visibility::Visibility,
|
visibility::Visibility,
|
||||||
|
@ -202,7 +202,7 @@ impl Crate {
|
||||||
|
|
||||||
pub fn root_module(self, db: &dyn HirDatabase) -> Module {
|
pub fn root_module(self, db: &dyn HirDatabase) -> Module {
|
||||||
let def_map = db.crate_def_map(self.id);
|
let def_map = db.crate_def_map(self.id);
|
||||||
Module { id: def_map.module_id(def_map.root()) }
|
Module { id: def_map.module_id(DefMap::ROOT) }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn modules(self, db: &dyn HirDatabase) -> Vec<Module> {
|
pub fn modules(self, db: &dyn HirDatabase) -> Vec<Module> {
|
||||||
|
@ -475,12 +475,11 @@ impl Module {
|
||||||
/// in the module tree of any target in `Cargo.toml`.
|
/// in the module tree of any target in `Cargo.toml`.
|
||||||
pub fn crate_root(self, db: &dyn HirDatabase) -> Module {
|
pub fn crate_root(self, db: &dyn HirDatabase) -> Module {
|
||||||
let def_map = db.crate_def_map(self.id.krate());
|
let def_map = db.crate_def_map(self.id.krate());
|
||||||
Module { id: def_map.module_id(def_map.root()) }
|
Module { id: def_map.module_id(DefMap::ROOT) }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_crate_root(self, db: &dyn HirDatabase) -> bool {
|
pub fn is_crate_root(self) -> bool {
|
||||||
let def_map = db.crate_def_map(self.id.krate());
|
DefMap::ROOT == self.id.local_id
|
||||||
def_map.root() == self.id.local_id
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Iterates over all child modules.
|
/// Iterates over all child modules.
|
||||||
|
|
|
@ -158,7 +158,7 @@ impl Completions {
|
||||||
path_ctx: &PathCompletionCtx,
|
path_ctx: &PathCompletionCtx,
|
||||||
) {
|
) {
|
||||||
ctx.process_all_names(&mut |name, res, doc_aliases| match res {
|
ctx.process_all_names(&mut |name, res, doc_aliases| match res {
|
||||||
ScopeDef::ModuleDef(hir::ModuleDef::Module(m)) if m.is_crate_root(ctx.db) => {
|
ScopeDef::ModuleDef(hir::ModuleDef::Module(m)) if m.is_crate_root() => {
|
||||||
self.add_module(ctx, path_ctx, m, name, doc_aliases);
|
self.add_module(ctx, path_ctx, m, name, doc_aliases);
|
||||||
}
|
}
|
||||||
_ => (),
|
_ => (),
|
||||||
|
|
|
@ -77,7 +77,7 @@ pub fn visit_file_defs(
|
||||||
}
|
}
|
||||||
module.impl_defs(db).into_iter().for_each(|impl_| cb(impl_.into()));
|
module.impl_defs(db).into_iter().for_each(|impl_| cb(impl_.into()));
|
||||||
|
|
||||||
let is_root = module.is_crate_root(db);
|
let is_root = module.is_crate_root();
|
||||||
module
|
module
|
||||||
.legacy_macros(db)
|
.legacy_macros(db)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
|
|
@ -178,7 +178,7 @@ fn rename_mod(
|
||||||
|
|
||||||
let mut source_change = SourceChange::default();
|
let mut source_change = SourceChange::default();
|
||||||
|
|
||||||
if module.is_crate_root(sema.db) {
|
if module.is_crate_root() {
|
||||||
return Ok(source_change);
|
return Ok(source_change);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -225,7 +225,7 @@ impl Definition {
|
||||||
// def is crate root
|
// def is crate root
|
||||||
// FIXME: We don't do searches for crates currently, as a crate does not actually have a single name
|
// FIXME: We don't do searches for crates currently, as a crate does not actually have a single name
|
||||||
if let &Definition::Module(module) = self {
|
if let &Definition::Module(module) = self {
|
||||||
if module.is_crate_root(db) {
|
if module.is_crate_root() {
|
||||||
return SearchScope::reverse_dependencies(db, module.krate());
|
return SearchScope::reverse_dependencies(db, module.krate());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -392,7 +392,7 @@ impl<'a> FindUsages<'a> {
|
||||||
|
|
||||||
let name = match self.def {
|
let name = match self.def {
|
||||||
// special case crate modules as these do not have a proper name
|
// special case crate modules as these do not have a proper name
|
||||||
Definition::Module(module) if module.is_crate_root(self.sema.db) => {
|
Definition::Module(module) if module.is_crate_root() => {
|
||||||
// FIXME: This assumes the crate name is always equal to its display name when it really isn't
|
// FIXME: This assumes the crate name is always equal to its display name when it really isn't
|
||||||
module
|
module
|
||||||
.krate()
|
.krate()
|
||||||
|
@ -500,7 +500,7 @@ impl<'a> FindUsages<'a> {
|
||||||
let scope =
|
let scope =
|
||||||
search_scope.intersection(&SearchScope::module_and_children(self.sema.db, module));
|
search_scope.intersection(&SearchScope::module_and_children(self.sema.db, module));
|
||||||
|
|
||||||
let is_crate_root = module.is_crate_root(self.sema.db).then(|| Finder::new("crate"));
|
let is_crate_root = module.is_crate_root().then(|| Finder::new("crate"));
|
||||||
let finder = &Finder::new("super");
|
let finder = &Finder::new("super");
|
||||||
|
|
||||||
for (text, file_id, search_range) in scope_files(sema, &scope) {
|
for (text, file_id, search_range) in scope_files(sema, &scope) {
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
use std::iter;
|
use std::iter;
|
||||||
|
|
||||||
use hir::{db::DefDatabase, InFile, ModuleSource};
|
use hir::{db::DefDatabase, DefMap, InFile, ModuleSource};
|
||||||
use ide_db::{
|
use ide_db::{
|
||||||
base_db::{FileId, FileLoader, SourceDatabase, SourceDatabaseExt},
|
base_db::{FileId, FileLoader, SourceDatabase, SourceDatabaseExt},
|
||||||
source_change::SourceChange,
|
source_change::SourceChange,
|
||||||
|
@ -74,7 +74,7 @@ fn fixes(ctx: &DiagnosticsContext<'_>, file_id: FileId) -> Option<Vec<Assist>> {
|
||||||
'crates: for &krate in &*ctx.sema.db.relevant_crates(file_id) {
|
'crates: for &krate in &*ctx.sema.db.relevant_crates(file_id) {
|
||||||
let crate_def_map = ctx.sema.db.crate_def_map(krate);
|
let crate_def_map = ctx.sema.db.crate_def_map(krate);
|
||||||
|
|
||||||
let root_module = &crate_def_map[crate_def_map.root()];
|
let root_module = &crate_def_map[DefMap::ROOT];
|
||||||
let Some(root_file_id) = root_module.origin.file_id() else { continue };
|
let Some(root_file_id) = root_module.origin.file_id() else { continue };
|
||||||
let Some(crate_root_path) = source_root.path_for_file(&root_file_id) else { continue };
|
let Some(crate_root_path) = source_root.path_for_file(&root_file_id) else { continue };
|
||||||
let Some(rel) = parent.strip_prefix(&crate_root_path.parent()?) else { continue };
|
let Some(rel) = parent.strip_prefix(&crate_root_path.parent()?) else { continue };
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use std::{fmt, marker::PhantomData};
|
use std::{fmt, marker::PhantomData};
|
||||||
|
|
||||||
use hir::{
|
use hir::{
|
||||||
db::{AstIdMapQuery, AttrsQuery, ParseMacroExpansionQuery},
|
db::{AstIdMapQuery, AttrsQuery, BlockDefMapQuery, ParseMacroExpansionQuery},
|
||||||
Attr, Attrs, ExpandResult, MacroFile, Module,
|
Attr, Attrs, ExpandResult, MacroFile, Module,
|
||||||
};
|
};
|
||||||
use ide_db::{
|
use ide_db::{
|
||||||
|
@ -51,6 +51,7 @@ pub(crate) fn status(db: &RootDatabase, file_id: Option<FileId>) -> String {
|
||||||
format_to!(buf, "\nDebug info:\n");
|
format_to!(buf, "\nDebug info:\n");
|
||||||
format_to!(buf, "{}\n", collect_query(AttrsQuery.in_db(db)));
|
format_to!(buf, "{}\n", collect_query(AttrsQuery.in_db(db)));
|
||||||
format_to!(buf, "{} ast id maps\n", collect_query_count(AstIdMapQuery.in_db(db)));
|
format_to!(buf, "{} ast id maps\n", collect_query_count(AstIdMapQuery.in_db(db)));
|
||||||
|
format_to!(buf, "{} block def maps\n", collect_query_count(BlockDefMapQuery.in_db(db)));
|
||||||
|
|
||||||
if let Some(file_id) = file_id {
|
if let Some(file_id) = file_id {
|
||||||
format_to!(buf, "\nFile info:\n");
|
format_to!(buf, "\nFile info:\n");
|
||||||
|
|
|
@ -340,7 +340,7 @@ fn highlight_def(
|
||||||
Definition::Field(_) => Highlight::new(HlTag::Symbol(SymbolKind::Field)),
|
Definition::Field(_) => Highlight::new(HlTag::Symbol(SymbolKind::Field)),
|
||||||
Definition::Module(module) => {
|
Definition::Module(module) => {
|
||||||
let mut h = Highlight::new(HlTag::Symbol(SymbolKind::Module));
|
let mut h = Highlight::new(HlTag::Symbol(SymbolKind::Module));
|
||||||
if module.is_crate_root(db) {
|
if module.is_crate_root() {
|
||||||
h |= HlMod::CrateRoot;
|
h |= HlMod::CrateRoot;
|
||||||
}
|
}
|
||||||
h
|
h
|
||||||
|
|
|
@ -18,6 +18,18 @@ pub use map::{ArenaMap, Entry, OccupiedEntry, VacantEntry};
|
||||||
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
pub struct RawIdx(u32);
|
pub struct RawIdx(u32);
|
||||||
|
|
||||||
|
impl RawIdx {
|
||||||
|
/// Constructs a [`RawIdx`] from a u32.
|
||||||
|
pub const fn from_u32(u32: u32) -> Self {
|
||||||
|
RawIdx(u32)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Deconstructs a [`RawIdx`] into the underlying u32.
|
||||||
|
pub const fn into_u32(self) -> u32 {
|
||||||
|
self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl From<RawIdx> for u32 {
|
impl From<RawIdx> for u32 {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn from(raw: RawIdx) -> u32 {
|
fn from(raw: RawIdx) -> u32 {
|
||||||
|
@ -94,12 +106,12 @@ impl<T> fmt::Debug for Idx<T> {
|
||||||
|
|
||||||
impl<T> Idx<T> {
|
impl<T> Idx<T> {
|
||||||
/// Creates a new index from a [`RawIdx`].
|
/// Creates a new index from a [`RawIdx`].
|
||||||
pub fn from_raw(raw: RawIdx) -> Self {
|
pub const fn from_raw(raw: RawIdx) -> Self {
|
||||||
Idx { raw, _ty: PhantomData }
|
Idx { raw, _ty: PhantomData }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Converts this index into the underlying [`RawIdx`].
|
/// Converts this index into the underlying [`RawIdx`].
|
||||||
pub fn into_raw(self) -> RawIdx {
|
pub const fn into_raw(self) -> RawIdx {
|
||||||
self.raw
|
self.raw
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue