Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir_def/src/nameres/collector.rs')
-rw-r--r--crates/hir_def/src/nameres/collector.rs56
1 files changed, 40 insertions, 16 deletions
diff --git a/crates/hir_def/src/nameres/collector.rs b/crates/hir_def/src/nameres/collector.rs
index d6762d1acf..53ab87005c 100644
--- a/crates/hir_def/src/nameres/collector.rs
+++ b/crates/hir_def/src/nameres/collector.rs
@@ -61,14 +61,17 @@ pub(super) fn collect_defs(
) -> DefMap {
let crate_graph = db.crate_graph();
- if block.is_none() {
- // populate external prelude
- for dep in &crate_graph[def_map.krate].dependencies {
- tracing::debug!("crate dep {:?} -> {:?}", dep.name, dep.crate_id);
- let dep_def_map = db.crate_def_map(dep.crate_id);
- def_map
- .extern_prelude
- .insert(dep.as_name(), dep_def_map.module_id(dep_def_map.root).into());
+ let mut deps = FxHashMap::default();
+ // populate external prelude and dependency list
+ for dep in &crate_graph[def_map.krate].dependencies {
+ 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.into());
+
+ if dep.is_prelude() && block.is_none() {
+ def_map.extern_prelude.insert(dep.as_name(), dep_root.into());
}
}
@@ -87,6 +90,7 @@ pub(super) fn collect_defs(
let mut collector = DefCollector {
db,
def_map,
+ deps,
glob_imports: FxHashMap::default(),
unresolved_imports: Vec::new(),
resolved_imports: Vec::new(),
@@ -239,6 +243,7 @@ struct DefData<'a> {
struct DefCollector<'a> {
db: &'a dyn DefDatabase,
def_map: DefMap,
+ deps: FxHashMap<Name, ModuleDefId>,
glob_imports: FxHashMap<LocalModuleId, Vec<(LocalModuleId, Visibility)>>,
unresolved_imports: Vec<ImportDirective>,
resolved_imports: Vec<ImportDirective>,
@@ -660,7 +665,7 @@ impl DefCollector<'_> {
self.def_map.edition,
);
- let res = self.def_map.resolve_name_in_extern_prelude(self.db, &extern_crate.name);
+ let res = self.resolve_extern_crate(&extern_crate.name);
if let Some(ModuleDefId::ModuleId(m)) = res.take_types() {
if m == self.def_map.module_id(current_module_id) {
@@ -720,13 +725,13 @@ impl DefCollector<'_> {
fn resolve_import(&self, module_id: LocalModuleId, import: &Import) -> PartialResolvedImport {
tracing::debug!("resolving import: {:?} ({:?})", import, self.def_map.edition);
if import.is_extern_crate {
- let res = self.def_map.resolve_name_in_extern_prelude(
- self.db,
- import
- .path
- .as_ident()
- .expect("extern crate should have been desugared to one-element path"),
- );
+ let name = import
+ .path
+ .as_ident()
+ .expect("extern crate should have been desugared to one-element path");
+
+ let res = self.resolve_extern_crate(name);
+
if res.is_none() {
PartialResolvedImport::Unresolved
} else {
@@ -766,6 +771,24 @@ impl DefCollector<'_> {
}
}
+ fn resolve_extern_crate(&self, name: &Name) -> PerNs {
+ let arc;
+ let root = match self.def_map.block {
+ Some(_) => {
+ arc = self.def_map.crate_root(self.db).def_map(self.db);
+ &*arc
+ }
+ None => &self.def_map,
+ };
+
+ if name == &name!(self) {
+ cov_mark::hit!(extern_crate_self_as);
+ PerNs::types(root.module_id(root.root()).into(), Visibility::Public)
+ } else {
+ self.deps.get(name).map_or(PerNs::none(), |&it| PerNs::types(it, Visibility::Public))
+ }
+ }
+
fn record_resolved_import(&mut self, directive: &ImportDirective) {
let module_id = directive.module_id;
let import = &directive.import;
@@ -2009,6 +2032,7 @@ mod tests {
let mut collector = DefCollector {
db,
def_map,
+ deps: FxHashMap::default(),
glob_imports: FxHashMap::default(),
unresolved_imports: Vec::new(),
resolved_imports: Vec::new(),