Auto merge of #15422 - Veykril:import-sources, r=Veykril
internal: Record import source IDs cc https://github.com/rust-lang/rust-analyzer/issues/14079
This commit is contained in:
commit
b78d69c795
@ -487,7 +487,7 @@ pub(crate) fn extern_crate_decl_data_query(
|
|||||||
db.crate_def_map(loc.container.krate())
|
db.crate_def_map(loc.container.krate())
|
||||||
.extern_prelude()
|
.extern_prelude()
|
||||||
.find(|&(prelude_name, ..)| *prelude_name == name)
|
.find(|&(prelude_name, ..)| *prelude_name == name)
|
||||||
.map(|(_, root)| root.krate())
|
.map(|(_, (root, _))| root.krate())
|
||||||
};
|
};
|
||||||
|
|
||||||
Arc::new(Self {
|
Arc::new(Self {
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
nameres::DefMap,
|
nameres::DefMap,
|
||||||
path::{ModPath, PathKind},
|
path::{ModPath, PathKind},
|
||||||
visibility::Visibility,
|
visibility::Visibility,
|
||||||
ModuleDefId, ModuleId,
|
CrateRootModuleId, ModuleDefId, ModuleId,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Find a path that can be used to refer to a certain item. This can depend on
|
/// Find a path that can be used to refer to a certain item. This can depend on
|
||||||
@ -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().into();
|
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();
|
||||||
@ -149,7 +149,7 @@ fn find_path_for_module(
|
|||||||
db: &dyn DefDatabase,
|
db: &dyn DefDatabase,
|
||||||
def_map: &DefMap,
|
def_map: &DefMap,
|
||||||
visited_modules: &mut FxHashSet<ModuleId>,
|
visited_modules: &mut FxHashSet<ModuleId>,
|
||||||
crate_root: ModuleId,
|
crate_root: CrateRootModuleId,
|
||||||
from: ModuleId,
|
from: ModuleId,
|
||||||
module_id: ModuleId,
|
module_id: ModuleId,
|
||||||
max_len: usize,
|
max_len: usize,
|
||||||
@ -183,7 +183,7 @@ fn find_path_for_module(
|
|||||||
|
|
||||||
// - if the item is the crate root of a dependency crate, return the name from the extern prelude
|
// - if the item is the crate root of a dependency crate, return the name from the extern prelude
|
||||||
let root_def_map = crate_root.def_map(db);
|
let root_def_map = crate_root.def_map(db);
|
||||||
for (name, def_id) in root_def_map.extern_prelude() {
|
for (name, (def_id, _extern_crate)) in root_def_map.extern_prelude() {
|
||||||
if module_id == def_id {
|
if module_id == def_id {
|
||||||
let name = scope_name.unwrap_or_else(|| name.clone());
|
let name = scope_name.unwrap_or_else(|| name.clone());
|
||||||
|
|
||||||
@ -192,7 +192,7 @@ fn find_path_for_module(
|
|||||||
def_map[local_id]
|
def_map[local_id]
|
||||||
.scope
|
.scope
|
||||||
.type_(&name)
|
.type_(&name)
|
||||||
.filter(|&(id, _)| id != ModuleDefId::ModuleId(def_id))
|
.filter(|&(id, _)| id != ModuleDefId::ModuleId(def_id.into()))
|
||||||
})
|
})
|
||||||
.is_some();
|
.is_some();
|
||||||
let kind = if name_already_occupied_in_type_ns {
|
let kind = if name_already_occupied_in_type_ns {
|
||||||
@ -244,7 +244,7 @@ fn find_in_prelude(
|
|||||||
item: ItemInNs,
|
item: ItemInNs,
|
||||||
from: ModuleId,
|
from: ModuleId,
|
||||||
) -> Option<ModPath> {
|
) -> Option<ModPath> {
|
||||||
let prelude_module = root_def_map.prelude()?;
|
let (prelude_module, _) = root_def_map.prelude()?;
|
||||||
// Preludes in block DefMaps are ignored, only the crate DefMap is searched
|
// Preludes in block DefMaps are ignored, only the crate DefMap is searched
|
||||||
let prelude_def_map = prelude_module.def_map(db);
|
let prelude_def_map = prelude_module.def_map(db);
|
||||||
let prelude_scope = &prelude_def_map[prelude_module.local_id].scope;
|
let prelude_scope = &prelude_def_map[prelude_module.local_id].scope;
|
||||||
@ -293,7 +293,7 @@ fn calculate_best_path(
|
|||||||
db: &dyn DefDatabase,
|
db: &dyn DefDatabase,
|
||||||
def_map: &DefMap,
|
def_map: &DefMap,
|
||||||
visited_modules: &mut FxHashSet<ModuleId>,
|
visited_modules: &mut FxHashSet<ModuleId>,
|
||||||
crate_root: ModuleId,
|
crate_root: CrateRootModuleId,
|
||||||
max_len: usize,
|
max_len: usize,
|
||||||
item: ItemInNs,
|
item: ItemInNs,
|
||||||
from: ModuleId,
|
from: ModuleId,
|
||||||
|
@ -109,6 +109,17 @@ pub fn krate(self) -> CrateId {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl PartialEq<ModuleId> for CrateRootModuleId {
|
||||||
|
fn eq(&self, other: &ModuleId) -> bool {
|
||||||
|
other.block.is_none() && other.local_id == DefMap::ROOT && self.krate == other.krate
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl PartialEq<CrateRootModuleId> for ModuleId {
|
||||||
|
fn eq(&self, other: &CrateRootModuleId) -> bool {
|
||||||
|
other == self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl From<CrateRootModuleId> for ModuleId {
|
impl From<CrateRootModuleId> for ModuleId {
|
||||||
fn from(CrateRootModuleId { krate }: CrateRootModuleId) -> Self {
|
fn from(CrateRootModuleId { krate }: CrateRootModuleId) -> Self {
|
||||||
ModuleId { krate, block: None, local_id: DefMap::ROOT }
|
ModuleId { krate, block: None, local_id: DefMap::ROOT }
|
||||||
|
@ -77,8 +77,8 @@
|
|||||||
path::ModPath,
|
path::ModPath,
|
||||||
per_ns::PerNs,
|
per_ns::PerNs,
|
||||||
visibility::Visibility,
|
visibility::Visibility,
|
||||||
AstId, BlockId, BlockLoc, CrateRootModuleId, FunctionId, LocalModuleId, Lookup, MacroExpander,
|
AstId, BlockId, BlockLoc, CrateRootModuleId, ExternCrateId, FunctionId, LocalModuleId, Lookup,
|
||||||
MacroId, ModuleId, ProcMacroId,
|
MacroExpander, MacroId, ModuleId, ProcMacroId, UseId,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Contains the results of (early) name resolution.
|
/// Contains the results of (early) name resolution.
|
||||||
@ -105,10 +105,10 @@ pub struct DefMap {
|
|||||||
/// The prelude is empty for non-block DefMaps (unless `#[prelude_import]` was used,
|
/// The prelude is empty for non-block DefMaps (unless `#[prelude_import]` was used,
|
||||||
/// 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, Option<UseId>)>,
|
||||||
/// `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, Option<ExternCrateId>)>,
|
||||||
|
|
||||||
/// Tracks which custom derives are in scope for an item, to allow resolution of derive helper
|
/// Tracks which custom derives are in scope for an item, to allow resolution of derive helper
|
||||||
/// attributes.
|
/// attributes.
|
||||||
@ -125,7 +125,7 @@ pub struct DefMap {
|
|||||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||||
struct DefMapCrateData {
|
struct DefMapCrateData {
|
||||||
/// The extern prelude which contains all root modules of external crates that are in scope.
|
/// The extern prelude which contains all root modules of external crates that are in scope.
|
||||||
extern_prelude: FxHashMap<Name, CrateRootModuleId>,
|
extern_prelude: FxHashMap<Name, (CrateRootModuleId, Option<ExternCrateId>)>,
|
||||||
|
|
||||||
/// Side table for resolving derive helpers.
|
/// Side table for resolving derive helpers.
|
||||||
exported_derives: FxHashMap<MacroDefId, Box<[Name]>>,
|
exported_derives: FxHashMap<MacroDefId, Box<[Name]>>,
|
||||||
@ -427,15 +427,19 @@ pub(crate) fn block_id(&self) -> Option<BlockId> {
|
|||||||
self.block.map(|block| block.block)
|
self.block.map(|block| block.block)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn prelude(&self) -> Option<ModuleId> {
|
pub(crate) fn prelude(&self) -> Option<(ModuleId, Option<UseId>)> {
|
||||||
self.prelude
|
self.prelude
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn extern_prelude(&self) -> impl Iterator<Item = (&Name, ModuleId)> + '_ {
|
pub(crate) fn extern_prelude(
|
||||||
self.data.extern_prelude.iter().map(|(name, &def)| (name, def.into()))
|
&self,
|
||||||
|
) -> impl Iterator<Item = (&Name, (CrateRootModuleId, Option<ExternCrateId>))> + '_ {
|
||||||
|
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, Option<ExternCrateId>))> + '_ {
|
||||||
self.macro_use_prelude.iter().map(|(name, &def)| (name, def))
|
self.macro_use_prelude.iter().map(|(name, &def)| (name, def))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,10 +52,10 @@
|
|||||||
tt,
|
tt,
|
||||||
visibility::{RawVisibility, Visibility},
|
visibility::{RawVisibility, Visibility},
|
||||||
AdtId, AstId, AstIdWithPath, ConstLoc, CrateRootModuleId, EnumLoc, EnumVariantId,
|
AdtId, AstId, AstIdWithPath, ConstLoc, CrateRootModuleId, EnumLoc, EnumVariantId,
|
||||||
ExternBlockLoc, ExternCrateLoc, FunctionId, FunctionLoc, ImplLoc, Intern, ItemContainerId,
|
ExternBlockLoc, ExternCrateId, ExternCrateLoc, FunctionId, FunctionLoc, ImplLoc, Intern,
|
||||||
LocalModuleId, Macro2Id, Macro2Loc, MacroExpander, MacroId, MacroRulesId, MacroRulesLoc,
|
ItemContainerId, LocalModuleId, Macro2Id, Macro2Loc, MacroExpander, MacroId, MacroRulesId,
|
||||||
ModuleDefId, ModuleId, ProcMacroId, ProcMacroLoc, StaticLoc, StructLoc, TraitAliasLoc,
|
MacroRulesLoc, ModuleDefId, ModuleId, ProcMacroId, ProcMacroLoc, StaticLoc, StructLoc,
|
||||||
TraitLoc, TypeAliasLoc, UnionLoc, UnresolvedMacro, UseLoc,
|
TraitAliasLoc, TraitLoc, TypeAliasLoc, UnionLoc, UnresolvedMacro, UseId, UseLoc,
|
||||||
};
|
};
|
||||||
|
|
||||||
static GLOB_RECURSION_LIMIT: Limit = Limit::new(100);
|
static GLOB_RECURSION_LIMIT: Limit = Limit::new(100);
|
||||||
@ -146,8 +146,8 @@ fn namespaces(self) -> PerNs {
|
|||||||
|
|
||||||
#[derive(Clone, Debug, Eq, PartialEq)]
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
||||||
enum ImportSource {
|
enum ImportSource {
|
||||||
Use { id: ItemTreeId<item_tree::Use>, use_tree: Idx<ast::UseTree> },
|
Use { use_tree: Idx<ast::UseTree>, id: UseId, is_prelude: bool },
|
||||||
ExternCrate(ItemTreeId<item_tree::ExternCrate>),
|
ExternCrate { id: ExternCrateId },
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Eq, PartialEq)]
|
#[derive(Debug, Eq, PartialEq)]
|
||||||
@ -157,52 +157,42 @@ struct Import {
|
|||||||
visibility: RawVisibility,
|
visibility: RawVisibility,
|
||||||
kind: ImportKind,
|
kind: ImportKind,
|
||||||
source: ImportSource,
|
source: ImportSource,
|
||||||
is_prelude: bool,
|
|
||||||
is_macro_use: bool,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Import {
|
impl Import {
|
||||||
fn from_use(
|
fn from_use(
|
||||||
db: &dyn DefDatabase,
|
|
||||||
krate: CrateId,
|
|
||||||
tree: &ItemTree,
|
tree: &ItemTree,
|
||||||
id: ItemTreeId<item_tree::Use>,
|
item_tree_id: ItemTreeId<item_tree::Use>,
|
||||||
|
id: UseId,
|
||||||
|
is_prelude: bool,
|
||||||
mut cb: impl FnMut(Self),
|
mut cb: impl FnMut(Self),
|
||||||
) {
|
) {
|
||||||
let it = &tree[id.value];
|
let it = &tree[item_tree_id.value];
|
||||||
let attrs = &tree.attrs(db, krate, ModItem::from(id.value).into());
|
|
||||||
let visibility = &tree[it.visibility];
|
let visibility = &tree[it.visibility];
|
||||||
let is_prelude = attrs.by_key("prelude_import").exists();
|
|
||||||
it.use_tree.expand(|idx, path, kind, alias| {
|
it.use_tree.expand(|idx, path, kind, alias| {
|
||||||
cb(Self {
|
cb(Self {
|
||||||
path,
|
path,
|
||||||
alias,
|
alias,
|
||||||
visibility: visibility.clone(),
|
visibility: visibility.clone(),
|
||||||
kind,
|
kind,
|
||||||
is_prelude,
|
source: ImportSource::Use { use_tree: idx, id, is_prelude },
|
||||||
is_macro_use: false,
|
|
||||||
source: ImportSource::Use { id, use_tree: idx },
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn from_extern_crate(
|
fn from_extern_crate(
|
||||||
db: &dyn DefDatabase,
|
|
||||||
krate: CrateId,
|
|
||||||
tree: &ItemTree,
|
tree: &ItemTree,
|
||||||
id: ItemTreeId<item_tree::ExternCrate>,
|
item_tree_id: ItemTreeId<item_tree::ExternCrate>,
|
||||||
|
id: ExternCrateId,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let it = &tree[id.value];
|
let it = &tree[item_tree_id.value];
|
||||||
let attrs = &tree.attrs(db, krate, ModItem::from(id.value).into());
|
|
||||||
let visibility = &tree[it.visibility];
|
let visibility = &tree[it.visibility];
|
||||||
Self {
|
Self {
|
||||||
path: ModPath::from_segments(PathKind::Plain, iter::once(it.name.clone())),
|
path: ModPath::from_segments(PathKind::Plain, iter::once(it.name.clone())),
|
||||||
alias: it.alias.clone(),
|
alias: it.alias.clone(),
|
||||||
visibility: visibility.clone(),
|
visibility: visibility.clone(),
|
||||||
kind: ImportKind::Plain,
|
kind: ImportKind::Plain,
|
||||||
is_prelude: false,
|
source: ImportSource::ExternCrate { id },
|
||||||
is_macro_use: attrs.by_key("macro_use").exists(),
|
|
||||||
source: ImportSource::ExternCrate(id),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -280,7 +270,7 @@ fn seed_with_top_level(&mut self) {
|
|||||||
if dep.is_prelude() {
|
if dep.is_prelude() {
|
||||||
crate_data
|
crate_data
|
||||||
.extern_prelude
|
.extern_prelude
|
||||||
.insert(name.clone(), CrateRootModuleId { krate: dep.crate_id });
|
.insert(name.clone(), (CrateRootModuleId { krate: dep.crate_id }, None));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -557,7 +547,7 @@ fn inject_prelude(&mut self) {
|
|||||||
|
|
||||||
match per_ns.types {
|
match per_ns.types {
|
||||||
Some((ModuleDefId::ModuleId(m), _)) => {
|
Some((ModuleDefId::ModuleId(m), _)) => {
|
||||||
self.def_map.prelude = Some(m);
|
self.def_map.prelude = Some((m, None));
|
||||||
}
|
}
|
||||||
types => {
|
types => {
|
||||||
tracing::debug!(
|
tracing::debug!(
|
||||||
@ -720,7 +710,13 @@ fn define_proc_macro(&mut self, name: Name, macro_: ProcMacroId) {
|
|||||||
/// Exported macros are just all macros in the root module scope.
|
/// Exported macros are just all macros in the root module scope.
|
||||||
/// Note that it contains not only all `#[macro_export]` macros, but also all aliases
|
/// Note that it contains not only all `#[macro_export]` macros, but also all aliases
|
||||||
/// created by `use` in the root module, ignoring the visibility of `use`.
|
/// created by `use` in the root module, ignoring the visibility of `use`.
|
||||||
fn import_macros_from_extern_crate(&mut self, krate: CrateId, names: Option<Vec<Name>>) {
|
fn import_macros_from_extern_crate(
|
||||||
|
&mut self,
|
||||||
|
krate: CrateId,
|
||||||
|
names: Option<Vec<Name>>,
|
||||||
|
|
||||||
|
extern_crate: Option<ExternCrateId>,
|
||||||
|
) {
|
||||||
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.
|
||||||
@ -729,12 +725,12 @@ fn import_macros_from_extern_crate(&mut self, krate: CrateId, names: Option<Vec<
|
|||||||
for name in names {
|
for name in names {
|
||||||
// FIXME: Report diagnostic on 404.
|
// FIXME: Report diagnostic on 404.
|
||||||
if let Some(def) = root_scope.get(&name).take_macros() {
|
if let Some(def) = root_scope.get(&name).take_macros() {
|
||||||
self.def_map.macro_use_prelude.insert(name, def);
|
self.def_map.macro_use_prelude.insert(name, (def, extern_crate));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (name, def) in root_scope.macros() {
|
for (name, def) in root_scope.macros() {
|
||||||
self.def_map.macro_use_prelude.insert(name.clone(), def);
|
self.def_map.macro_use_prelude.insert(name.clone(), (def, extern_crate));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -771,48 +767,52 @@ fn resolve_import(&self, module_id: LocalModuleId, import: &Import) -> PartialRe
|
|||||||
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.data.edition);
|
tracing::debug!("resolving import: {:?} ({:?})", import, self.def_map.data.edition);
|
||||||
if matches!(import.source, ImportSource::ExternCrate { .. }) {
|
match import.source {
|
||||||
let name = import
|
ImportSource::ExternCrate { .. } => {
|
||||||
.path
|
let name = import
|
||||||
.as_ident()
|
.path
|
||||||
.expect("extern crate should have been desugared to one-element path");
|
.as_ident()
|
||||||
|
.expect("extern crate should have been desugared to one-element path");
|
||||||
|
|
||||||
let res = self.resolve_extern_crate(name);
|
let res = self.resolve_extern_crate(name);
|
||||||
|
|
||||||
match res {
|
match res {
|
||||||
Some(res) => {
|
Some(res) => PartialResolvedImport::Resolved(PerNs::types(
|
||||||
PartialResolvedImport::Resolved(PerNs::types(res.into(), Visibility::Public))
|
res.into(),
|
||||||
}
|
Visibility::Public,
|
||||||
None => PartialResolvedImport::Unresolved,
|
)),
|
||||||
}
|
None => PartialResolvedImport::Unresolved,
|
||||||
} else {
|
|
||||||
let res = self.def_map.resolve_path_fp_with_macro(
|
|
||||||
self.db,
|
|
||||||
ResolveMode::Import,
|
|
||||||
module_id,
|
|
||||||
&import.path,
|
|
||||||
BuiltinShadowMode::Module,
|
|
||||||
None, // An import may resolve to any kind of macro.
|
|
||||||
);
|
|
||||||
|
|
||||||
let def = res.resolved_def;
|
|
||||||
if res.reached_fixedpoint == ReachedFixedPoint::No || def.is_none() {
|
|
||||||
return PartialResolvedImport::Unresolved;
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(krate) = res.krate {
|
|
||||||
if krate != self.def_map.krate {
|
|
||||||
return PartialResolvedImport::Resolved(
|
|
||||||
def.filter_visibility(|v| matches!(v, Visibility::Public)),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ImportSource::Use { .. } => {
|
||||||
|
let res = self.def_map.resolve_path_fp_with_macro(
|
||||||
|
self.db,
|
||||||
|
ResolveMode::Import,
|
||||||
|
module_id,
|
||||||
|
&import.path,
|
||||||
|
BuiltinShadowMode::Module,
|
||||||
|
None, // An import may resolve to any kind of macro.
|
||||||
|
);
|
||||||
|
|
||||||
// Check whether all namespaces are resolved.
|
let def = res.resolved_def;
|
||||||
if def.is_full() {
|
if res.reached_fixedpoint == ReachedFixedPoint::No || def.is_none() {
|
||||||
PartialResolvedImport::Resolved(def)
|
return PartialResolvedImport::Unresolved;
|
||||||
} else {
|
}
|
||||||
PartialResolvedImport::Indeterminate(def)
|
|
||||||
|
if let Some(krate) = res.krate {
|
||||||
|
if krate != self.def_map.krate {
|
||||||
|
return PartialResolvedImport::Resolved(
|
||||||
|
def.filter_visibility(|v| matches!(v, Visibility::Public)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check whether all namespaces are resolved.
|
||||||
|
if def.is_full() {
|
||||||
|
PartialResolvedImport::Resolved(def)
|
||||||
|
} else {
|
||||||
|
PartialResolvedImport::Indeterminate(def)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -859,17 +859,17 @@ fn record_resolved_import(&mut self, directive: &ImportDirective) {
|
|||||||
tracing::debug!("resolved import {:?} ({:?}) to {:?}", name, import, def);
|
tracing::debug!("resolved import {:?} ({:?}) to {:?}", name, import, def);
|
||||||
|
|
||||||
// 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 matches!(import.source, ImportSource::ExternCrate { .. })
|
if let ImportSource::ExternCrate { id, .. } = import.source {
|
||||||
&& self.def_map.block.is_none()
|
if self.def_map.block.is_none() && module_id == DefMap::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)
|
{
|
||||||
{
|
if let Ok(def) = def.try_into() {
|
||||||
if let Ok(def) = def.try_into() {
|
Arc::get_mut(&mut self.def_map.data)
|
||||||
Arc::get_mut(&mut self.def_map.data)
|
.unwrap()
|
||||||
.unwrap()
|
.extern_prelude
|
||||||
.extern_prelude
|
.insert(name.clone(), (def, Some(id)));
|
||||||
.insert(name.clone(), def);
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -880,11 +880,11 @@ fn record_resolved_import(&mut self, directive: &ImportDirective) {
|
|||||||
tracing::debug!("glob import: {:?}", import);
|
tracing::debug!("glob import: {:?}", import);
|
||||||
match def.take_types() {
|
match def.take_types() {
|
||||||
Some(ModuleDefId::ModuleId(m)) => {
|
Some(ModuleDefId::ModuleId(m)) => {
|
||||||
if import.is_prelude {
|
if let ImportSource::Use { id, is_prelude: true, .. } = import.source {
|
||||||
// Note: This dodgily overrides the injected prelude. The rustc
|
// Note: This dodgily overrides the injected prelude. The rustc
|
||||||
// implementation seems to work the same though.
|
// implementation seems to work the same though.
|
||||||
cov_mark::hit!(std_prelude);
|
cov_mark::hit!(std_prelude);
|
||||||
self.def_map.prelude = Some(m);
|
self.def_map.prelude = Some((m, Some(id)));
|
||||||
} else if m.krate != self.def_map.krate {
|
} else if m.krate != self.def_map.krate {
|
||||||
cov_mark::hit!(glob_across_crates);
|
cov_mark::hit!(glob_across_crates);
|
||||||
// glob import from other crate => we can just import everything once
|
// glob import from other crate => we can just import everything once
|
||||||
@ -1460,31 +1460,32 @@ fn finish(mut self) -> DefMap {
|
|||||||
// heuristic, but it works in practice.
|
// heuristic, but it works in practice.
|
||||||
let mut diagnosed_extern_crates = FxHashSet::default();
|
let mut diagnosed_extern_crates = FxHashSet::default();
|
||||||
for directive in &self.unresolved_imports {
|
for directive in &self.unresolved_imports {
|
||||||
if let ImportSource::ExternCrate(krate) = directive.import.source {
|
if let ImportSource::ExternCrate { id } = directive.import.source {
|
||||||
let item_tree = krate.item_tree(self.db);
|
let item_tree_id = self.db.lookup_intern_extern_crate(id).id;
|
||||||
let extern_crate = &item_tree[krate.value];
|
let item_tree = item_tree_id.item_tree(self.db);
|
||||||
|
let extern_crate = &item_tree[item_tree_id.value];
|
||||||
|
|
||||||
diagnosed_extern_crates.insert(extern_crate.name.clone());
|
diagnosed_extern_crates.insert(extern_crate.name.clone());
|
||||||
|
|
||||||
self.def_map.diagnostics.push(DefDiagnostic::unresolved_extern_crate(
|
self.def_map.diagnostics.push(DefDiagnostic::unresolved_extern_crate(
|
||||||
directive.module_id,
|
directive.module_id,
|
||||||
InFile::new(krate.file_id(), extern_crate.ast_id),
|
InFile::new(item_tree_id.file_id(), extern_crate.ast_id),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for directive in &self.unresolved_imports {
|
for directive in &self.unresolved_imports {
|
||||||
if let ImportSource::Use { id: import, use_tree } = directive.import.source {
|
if let ImportSource::Use { use_tree, id, is_prelude: _ } = directive.import.source {
|
||||||
if matches!(
|
if matches!(
|
||||||
(directive.import.path.segments().first(), &directive.import.path.kind),
|
(directive.import.path.segments().first(), &directive.import.path.kind),
|
||||||
(Some(krate), PathKind::Plain | PathKind::Abs) if diagnosed_extern_crates.contains(krate)
|
(Some(krate), PathKind::Plain | PathKind::Abs) if diagnosed_extern_crates.contains(krate)
|
||||||
) {
|
) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
let item_tree_id = self.db.lookup_intern_use(id).id;
|
||||||
self.def_map.diagnostics.push(DefDiagnostic::unresolved_import(
|
self.def_map.diagnostics.push(DefDiagnostic::unresolved_import(
|
||||||
directive.module_id,
|
directive.module_id,
|
||||||
import,
|
item_tree_id,
|
||||||
use_tree,
|
use_tree,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
@ -1519,72 +1520,66 @@ fn collect(&mut self, items: &[ModItem], container: ItemContainerId) {
|
|||||||
self.def_collector.mod_dirs.insert(self.module_id, self.mod_dir.clone());
|
self.def_collector.mod_dirs.insert(self.module_id, self.mod_dir.clone());
|
||||||
|
|
||||||
// Prelude module is always considered to be `#[macro_use]`.
|
// Prelude module is always considered to be `#[macro_use]`.
|
||||||
if let Some(prelude_module) = self.def_collector.def_map.prelude {
|
if let Some((prelude_module, _use)) = self.def_collector.def_map.prelude {
|
||||||
if prelude_module.krate != krate && is_crate_root {
|
if prelude_module.krate != krate && is_crate_root {
|
||||||
cov_mark::hit!(prelude_is_macro_use);
|
cov_mark::hit!(prelude_is_macro_use);
|
||||||
self.def_collector.import_macros_from_extern_crate(prelude_module.krate, None);
|
self.def_collector.import_macros_from_extern_crate(
|
||||||
|
prelude_module.krate,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
let db = self.def_collector.db;
|
||||||
|
let module_id = self.module_id;
|
||||||
|
let update_def =
|
||||||
|
|def_collector: &mut DefCollector<'_>, id, name: &Name, vis, has_constructor| {
|
||||||
|
def_collector.def_map.modules[module_id].scope.declare(id);
|
||||||
|
def_collector.update(
|
||||||
|
module_id,
|
||||||
|
&[(Some(name.clone()), PerNs::from_def(id, vis, has_constructor))],
|
||||||
|
vis,
|
||||||
|
ImportType::Named,
|
||||||
|
)
|
||||||
|
};
|
||||||
|
let resolve_vis = |def_map: &DefMap, visibility| {
|
||||||
|
def_map
|
||||||
|
.resolve_visibility(db, module_id, visibility, false)
|
||||||
|
.unwrap_or(Visibility::Public)
|
||||||
|
};
|
||||||
|
|
||||||
// This should be processed eagerly instead of deferred to resolving.
|
let mut process_mod_item = |item: ModItem| {
|
||||||
// `#[macro_use] extern crate` is hoisted to imports macros before collecting
|
let attrs = self.item_tree.attrs(db, krate, item.into());
|
||||||
// any other items.
|
|
||||||
//
|
|
||||||
// If we're not at the crate root, `macro_use`d extern crates are an error so let's just
|
|
||||||
// ignore them.
|
|
||||||
if is_crate_root {
|
|
||||||
for &item in items {
|
|
||||||
if let ModItem::ExternCrate(id) = item {
|
|
||||||
self.process_macro_use_extern_crate(id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for &item in items {
|
|
||||||
let attrs = self.item_tree.attrs(self.def_collector.db, krate, item.into());
|
|
||||||
if let Some(cfg) = attrs.cfg() {
|
if let Some(cfg) = attrs.cfg() {
|
||||||
if !self.is_cfg_enabled(&cfg) {
|
if !self.is_cfg_enabled(&cfg) {
|
||||||
self.emit_unconfigured_diagnostic(item, &cfg);
|
self.emit_unconfigured_diagnostic(item, &cfg);
|
||||||
continue;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Err(()) = self.resolve_attributes(&attrs, item, container) {
|
if let Err(()) = self.resolve_attributes(&attrs, item, container) {
|
||||||
// Do not process the item. It has at least one non-builtin attribute, so the
|
// Do not process the item. It has at least one non-builtin attribute, so the
|
||||||
// fixed-point algorithm is required to resolve the rest of them.
|
// fixed-point algorithm is required to resolve the rest of them.
|
||||||
continue;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let db = self.def_collector.db;
|
let module = self.def_collector.def_map.module_id(module_id);
|
||||||
let module = self.def_collector.def_map.module_id(self.module_id);
|
|
||||||
let def_map = &mut self.def_collector.def_map;
|
let def_map = &mut self.def_collector.def_map;
|
||||||
let update_def =
|
|
||||||
|def_collector: &mut DefCollector<'_>, id, name: &Name, vis, has_constructor| {
|
|
||||||
def_collector.def_map.modules[self.module_id].scope.declare(id);
|
|
||||||
def_collector.update(
|
|
||||||
self.module_id,
|
|
||||||
&[(Some(name.clone()), PerNs::from_def(id, vis, has_constructor))],
|
|
||||||
vis,
|
|
||||||
ImportType::Named,
|
|
||||||
)
|
|
||||||
};
|
|
||||||
let resolve_vis = |def_map: &DefMap, visibility| {
|
|
||||||
def_map
|
|
||||||
.resolve_visibility(db, self.module_id, visibility, false)
|
|
||||||
.unwrap_or(Visibility::Public)
|
|
||||||
};
|
|
||||||
|
|
||||||
match item {
|
match item {
|
||||||
ModItem::Mod(m) => self.collect_module(m, &attrs),
|
ModItem::Mod(m) => self.collect_module(m, &attrs),
|
||||||
ModItem::Use(import_id) => {
|
ModItem::Use(item_tree_id) => {
|
||||||
let _import_id =
|
let id = UseLoc {
|
||||||
UseLoc { container: module, id: ItemTreeId::new(self.tree_id, import_id) }
|
container: module,
|
||||||
.intern(db);
|
id: ItemTreeId::new(self.tree_id, item_tree_id),
|
||||||
|
}
|
||||||
|
.intern(db);
|
||||||
|
let is_prelude = attrs.by_key("prelude_import").exists();
|
||||||
Import::from_use(
|
Import::from_use(
|
||||||
db,
|
|
||||||
krate,
|
|
||||||
self.item_tree,
|
self.item_tree,
|
||||||
ItemTreeId::new(self.tree_id, import_id),
|
ItemTreeId::new(self.tree_id, item_tree_id),
|
||||||
|
id,
|
||||||
|
is_prelude,
|
||||||
|import| {
|
|import| {
|
||||||
self.def_collector.unresolved_imports.push(ImportDirective {
|
self.def_collector.unresolved_imports.push(ImportDirective {
|
||||||
module_id: self.module_id,
|
module_id: self.module_id,
|
||||||
@ -1594,22 +1589,29 @@ fn collect(&mut self, items: &[ModItem], container: ItemContainerId) {
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
ModItem::ExternCrate(import_id) => {
|
ModItem::ExternCrate(item_tree_id) => {
|
||||||
let extern_crate_id = ExternCrateLoc {
|
let id = ExternCrateLoc {
|
||||||
container: module,
|
container: module,
|
||||||
id: ItemTreeId::new(self.tree_id, import_id),
|
id: ItemTreeId::new(self.tree_id, item_tree_id),
|
||||||
}
|
}
|
||||||
.intern(db);
|
.intern(db);
|
||||||
|
if is_crate_root {
|
||||||
|
self.process_macro_use_extern_crate(
|
||||||
|
item_tree_id,
|
||||||
|
id,
|
||||||
|
attrs.by_key("macro_use").attrs(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
self.def_collector.def_map.modules[self.module_id]
|
self.def_collector.def_map.modules[self.module_id]
|
||||||
.scope
|
.scope
|
||||||
.define_extern_crate_decl(extern_crate_id);
|
.define_extern_crate_decl(id);
|
||||||
self.def_collector.unresolved_imports.push(ImportDirective {
|
self.def_collector.unresolved_imports.push(ImportDirective {
|
||||||
module_id: self.module_id,
|
module_id: self.module_id,
|
||||||
import: Import::from_extern_crate(
|
import: Import::from_extern_crate(
|
||||||
db,
|
|
||||||
krate,
|
|
||||||
self.item_tree,
|
self.item_tree,
|
||||||
ItemTreeId::new(self.tree_id, import_id),
|
ItemTreeId::new(self.tree_id, item_tree_id),
|
||||||
|
id,
|
||||||
),
|
),
|
||||||
status: PartialResolvedImport::Unresolved,
|
status: PartialResolvedImport::Unresolved,
|
||||||
})
|
})
|
||||||
@ -1768,21 +1770,34 @@ fn collect(&mut self, items: &[ModItem], container: ItemContainerId) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// extern crates should be processed eagerly instead of deferred to resolving.
|
||||||
|
// `#[macro_use] extern crate` is hoisted to imports macros before collecting
|
||||||
|
// any other items.
|
||||||
|
if is_crate_root {
|
||||||
|
items
|
||||||
|
.iter()
|
||||||
|
.filter(|it| matches!(it, ModItem::ExternCrate(..)))
|
||||||
|
.copied()
|
||||||
|
.for_each(&mut process_mod_item);
|
||||||
|
items
|
||||||
|
.iter()
|
||||||
|
.filter(|it| !matches!(it, ModItem::ExternCrate(..)))
|
||||||
|
.copied()
|
||||||
|
.for_each(process_mod_item);
|
||||||
|
} else {
|
||||||
|
items.iter().copied().for_each(process_mod_item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn process_macro_use_extern_crate(&mut self, extern_crate: FileItemTreeId<ExternCrate>) {
|
fn process_macro_use_extern_crate<'a>(
|
||||||
|
&mut self,
|
||||||
|
extern_crate: FileItemTreeId<ExternCrate>,
|
||||||
|
extern_crate_id: ExternCrateId,
|
||||||
|
macro_use_attrs: impl Iterator<Item = &'a Attr>,
|
||||||
|
) {
|
||||||
let db = self.def_collector.db;
|
let db = self.def_collector.db;
|
||||||
let attrs = self.item_tree.attrs(
|
|
||||||
db,
|
|
||||||
self.def_collector.def_map.krate,
|
|
||||||
ModItem::from(extern_crate).into(),
|
|
||||||
);
|
|
||||||
if let Some(cfg) = attrs.cfg() {
|
|
||||||
if !self.is_cfg_enabled(&cfg) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let target_crate =
|
let target_crate =
|
||||||
match self.def_collector.resolve_extern_crate(&self.item_tree[extern_crate].name) {
|
match self.def_collector.resolve_extern_crate(&self.item_tree[extern_crate].name) {
|
||||||
@ -1798,11 +1813,11 @@ fn process_macro_use_extern_crate(&mut self, extern_crate: FileItemTreeId<Extern
|
|||||||
|
|
||||||
let mut single_imports = Vec::new();
|
let mut single_imports = Vec::new();
|
||||||
let hygiene = Hygiene::new_unhygienic();
|
let hygiene = Hygiene::new_unhygienic();
|
||||||
for attr in attrs.by_key("macro_use").attrs() {
|
for attr in macro_use_attrs {
|
||||||
let Some(paths) = attr.parse_path_comma_token_tree(db.upcast(), &hygiene) else {
|
let Some(paths) = attr.parse_path_comma_token_tree(db.upcast(), &hygiene) else {
|
||||||
// `#[macro_use]` (without any paths) found, forget collected names and just import
|
// `#[macro_use]` (without any paths) found, forget collected names and just import
|
||||||
// all visible macros.
|
// all visible macros.
|
||||||
self.def_collector.import_macros_from_extern_crate(target_crate, None);
|
self.def_collector.import_macros_from_extern_crate(target_crate, None, Some(extern_crate_id));
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
for path in paths {
|
for path in paths {
|
||||||
@ -1812,7 +1827,11 @@ fn process_macro_use_extern_crate(&mut self, extern_crate: FileItemTreeId<Extern
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.def_collector.import_macros_from_extern_crate(target_crate, Some(single_imports));
|
self.def_collector.import_macros_from_extern_crate(
|
||||||
|
target_crate,
|
||||||
|
Some(single_imports),
|
||||||
|
Some(extern_crate_id),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn collect_module(&mut self, module_id: FileItemTreeId<Mod>, attrs: &Attrs) {
|
fn collect_module(&mut self, module_id: FileItemTreeId<Mod>, attrs: &Attrs) {
|
||||||
@ -2198,7 +2217,7 @@ fn collect_macro_call(&mut self, mac: &MacroCall, container: ItemContainerId) {
|
|||||||
map[module].scope.get_legacy_macro(name)?.last().copied()
|
map[module].scope.get_legacy_macro(name)?.last().copied()
|
||||||
})
|
})
|
||||||
.or_else(|| def_map[self.module_id].scope.get(name).take_macros())
|
.or_else(|| def_map[self.module_id].scope.get(name).take_macros())
|
||||||
.or_else(|| def_map.macro_use_prelude.get(name).copied())
|
.or_else(|| Some(def_map.macro_use_prelude.get(name).copied()?.0))
|
||||||
.filter(|&id| {
|
.filter(|&id| {
|
||||||
sub_namespace_match(
|
sub_namespace_match(
|
||||||
Some(MacroSubNs::from_id(db, id)),
|
Some(MacroSubNs::from_id(db, id)),
|
||||||
|
@ -299,7 +299,7 @@ pub(super) fn resolve_path_fp_with_macro_single(
|
|||||||
Some((_, segment)) => segment,
|
Some((_, segment)) => segment,
|
||||||
None => return ResolvePathResult::empty(ReachedFixedPoint::Yes),
|
None => return ResolvePathResult::empty(ReachedFixedPoint::Yes),
|
||||||
};
|
};
|
||||||
if let Some(&def) = self.data.extern_prelude.get(segment) {
|
if let Some(&(def, _extern_crate)) = 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 {
|
||||||
@ -452,15 +452,14 @@ fn resolve_name_in_module(
|
|||||||
// Don't resolve extern prelude in block `DefMap`s.
|
// Don't resolve extern prelude in block `DefMap`s.
|
||||||
return PerNs::none();
|
return PerNs::none();
|
||||||
}
|
}
|
||||||
self.data
|
self.data.extern_prelude.get(name).map_or(PerNs::none(), |&(it, _extern_crate)| {
|
||||||
.extern_prelude
|
PerNs::types(it.into(), Visibility::Public)
|
||||||
.get(name)
|
})
|
||||||
.map_or(PerNs::none(), |&it| PerNs::types(it.into(), Visibility::Public))
|
|
||||||
};
|
};
|
||||||
let macro_use_prelude = || {
|
let macro_use_prelude = || {
|
||||||
self.macro_use_prelude
|
self.macro_use_prelude.get(name).map_or(PerNs::none(), |&(it, _extern_crate)| {
|
||||||
.get(name)
|
PerNs::macros(it.into(), Visibility::Public)
|
||||||
.map_or(PerNs::none(), |&it| PerNs::macros(it.into(), Visibility::Public))
|
})
|
||||||
};
|
};
|
||||||
let prelude = || self.resolve_in_prelude(db, name);
|
let prelude = || self.resolve_in_prelude(db, name);
|
||||||
|
|
||||||
@ -492,14 +491,16 @@ fn resolve_name_in_crate_root_or_extern_prelude(
|
|||||||
.extern_prelude
|
.extern_prelude
|
||||||
.get(name)
|
.get(name)
|
||||||
.copied()
|
.copied()
|
||||||
.map_or(PerNs::none(), |it| PerNs::types(it.into(), Visibility::Public))
|
.map_or(PerNs::none(), |(it, _extern_crate)| {
|
||||||
|
PerNs::types(it.into(), Visibility::Public)
|
||||||
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
from_crate_root.or_else(from_extern_prelude)
|
from_crate_root.or_else(from_extern_prelude)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn resolve_in_prelude(&self, db: &dyn DefDatabase, name: &Name) -> PerNs {
|
fn resolve_in_prelude(&self, db: &dyn DefDatabase, name: &Name) -> PerNs {
|
||||||
if let Some(prelude) = self.prelude {
|
if let Some((prelude, _use)) = self.prelude {
|
||||||
let keep;
|
let keep;
|
||||||
let def_map = if prelude.krate == self.krate {
|
let def_map = if prelude.krate == self.krate {
|
||||||
self
|
self
|
||||||
|
@ -433,16 +433,16 @@ pub fn names_in_scope(
|
|||||||
res.add(name, ScopeDef::ModuleDef(ModuleDefId::MacroId(mac)));
|
res.add(name, ScopeDef::ModuleDef(ModuleDefId::MacroId(mac)));
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
def_map.macro_use_prelude().for_each(|(name, def)| {
|
def_map.macro_use_prelude().for_each(|(name, (def, _extern_crate))| {
|
||||||
res.add(name, ScopeDef::ModuleDef(def.into()));
|
res.add(name, ScopeDef::ModuleDef(def.into()));
|
||||||
});
|
});
|
||||||
def_map.extern_prelude().for_each(|(name, def)| {
|
def_map.extern_prelude().for_each(|(name, (def, _extern_crate))| {
|
||||||
res.add(name, ScopeDef::ModuleDef(ModuleDefId::ModuleId(def)));
|
res.add(name, ScopeDef::ModuleDef(ModuleDefId::ModuleId(def.into())));
|
||||||
});
|
});
|
||||||
BUILTIN_SCOPE.iter().for_each(|(name, &def)| {
|
BUILTIN_SCOPE.iter().for_each(|(name, &def)| {
|
||||||
res.add_per_ns(name, def);
|
res.add_per_ns(name, def);
|
||||||
});
|
});
|
||||||
if let Some(prelude) = def_map.prelude() {
|
if let Some((prelude, _use)) = def_map.prelude() {
|
||||||
let prelude_def_map = prelude.def_map(db);
|
let prelude_def_map = prelude.def_map(db);
|
||||||
for (name, def) in prelude_def_map[prelude.local_id].scope.entries() {
|
for (name, def) in prelude_def_map[prelude.local_id].scope.entries() {
|
||||||
res.add_per_ns(name, def)
|
res.add_per_ns(name, def)
|
||||||
@ -473,7 +473,7 @@ pub fn traits_in_scope(&self, db: &dyn DefDatabase) -> FxHashSet<TraitId> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Fill in the prelude traits
|
// Fill in the prelude traits
|
||||||
if let Some(prelude) = self.module_scope.def_map.prelude() {
|
if let Some((prelude, _use)) = self.module_scope.def_map.prelude() {
|
||||||
let prelude_def_map = prelude.def_map(db);
|
let prelude_def_map = prelude.def_map(db);
|
||||||
traits.extend(prelude_def_map[prelude.local_id].scope.traits());
|
traits.extend(prelude_def_map[prelude.local_id].scope.traits());
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user