about summary refs log tree commit diff
diff options
context:
space:
mode:
authorLukas Wirth <lukastw97@gmail.com>2023-06-01 17:58:08 +0200
committerLukas Wirth <lukastw97@gmail.com>2023-06-01 17:58:08 +0200
commit11b937177bbad6afcffebefd7cd81934ae6b0baa (patch)
treebb47b1eff17e1cc9a6a6b3fc375efd46c1b293da
parent54e3ef658a83dea6a9af282627496114df6dd641 (diff)
downloadrust-11b937177bbad6afcffebefd7cd81934ae6b0baa.tar.gz
rust-11b937177bbad6afcffebefd7cd81934ae6b0baa.zip
Skip extern prelude path resolution in block def maps
-rw-r--r--crates/hir-def/src/find_path.rs4
-rw-r--r--crates/hir-def/src/nameres.rs11
-rw-r--r--crates/hir-def/src/nameres/collector.rs6
-rw-r--r--crates/hir-def/src/nameres/path_resolution.rs32
4 files changed, 21 insertions, 32 deletions
diff --git a/crates/hir-def/src/find_path.rs b/crates/hir-def/src/find_path.rs
index 1e299fecc9d..e8cc2eab461 100644
--- a/crates/hir-def/src/find_path.rs
+++ b/crates/hir-def/src/find_path.rs
@@ -81,7 +81,7 @@ fn find_path_inner(
     }
 
     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 let ItemInNs::Types(ModuleDefId::ModuleId(module_id)) = item {
         let mut visited_modules = FxHashSet::default();
@@ -454,7 +454,7 @@ fn find_local_import_locations(
         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();
 
diff --git a/crates/hir-def/src/nameres.rs b/crates/hir-def/src/nameres.rs
index b5a30f9d885..9b520bc3030 100644
--- a/crates/hir-def/src/nameres.rs
+++ b/crates/hir-def/src/nameres.rs
@@ -431,15 +431,8 @@ impl DefMap {
         ModuleId { krate: self.krate, local_id, block }
     }
 
-    pub(crate) fn crate_root(&self, db: &dyn DefDatabase) -> ModuleId {
-        self.with_ancestor_maps(db, Self::ROOT, &mut |def_map, _module| {
-            if def_map.block.is_none() {
-                Some(def_map.module_id(Self::ROOT))
-            } else {
-                None
-            }
-        })
-        .expect("DefMap chain without root")
+    pub(crate) fn crate_root(&self) -> ModuleId {
+        ModuleId { krate: self.krate, block: None, local_id: DefMap::ROOT }
     }
 
     pub(crate) fn resolve_path(
diff --git a/crates/hir-def/src/nameres/collector.rs b/crates/hir-def/src/nameres/collector.rs
index 29ee13648ea..06542b4b1e9 100644
--- a/crates/hir-def/src/nameres/collector.rs
+++ b/crates/hir-def/src/nameres/collector.rs
@@ -834,11 +834,7 @@ impl DefCollector<'_> {
     fn resolve_extern_crate(&self, name: &Name) -> Option<ModuleId> {
         if *name == name!(self) {
             cov_mark::hit!(extern_crate_self_as);
-            let root = match self.def_map.block {
-                Some(_) => self.def_map.crate_root(self.db),
-                None => self.def_map.module_id(DefMap::ROOT),
-            };
-            Some(root)
+            Some(self.def_map.crate_root())
         } else {
             self.deps.get(name).map(|dep| ModuleId {
                 krate: dep.crate_id,
diff --git a/crates/hir-def/src/nameres/path_resolution.rs b/crates/hir-def/src/nameres/path_resolution.rs
index c5335aaf121..5f6163175a7 100644
--- a/crates/hir-def/src/nameres/path_resolution.rs
+++ b/crates/hir-def/src/nameres/path_resolution.rs
@@ -20,7 +20,7 @@ use crate::{
     path::{ModPath, PathKind},
     per_ns::PerNs,
     visibility::{RawVisibility, Visibility},
-    AdtId, CrateId, EnumVariantId, LocalModuleId, ModuleDefId, ModuleId,
+    AdtId, CrateId, EnumVariantId, LocalModuleId, ModuleDefId,
 };
 
 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
@@ -74,17 +74,6 @@ impl PerNs {
 }
 
 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).data.extern_prelude.get(name).copied(),
-            None => self.data.extern_prelude.get(name).copied(),
-        }
-    }
-
     pub(crate) fn resolve_visibility(
         &self,
         db: &dyn DefDatabase,
@@ -204,7 +193,7 @@ impl DefMap {
             PathKind::DollarCrate(krate) => {
                 if krate == self.krate {
                     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 {
                     let def_map = db.crate_def_map(krate);
                     let module = def_map.module_id(Self::ROOT);
@@ -212,7 +201,7 @@ impl DefMap {
                     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
             // fallback to extern prelude (with the simplification in
             // rust-lang/rust#57745)
@@ -453,6 +442,10 @@ impl DefMap {
         };
 
         let 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)
@@ -479,13 +472,20 @@ impl DefMap {
     ) -> PerNs {
         let from_crate_root = match self.block {
             Some(_) => {
-                let def_map = self.crate_root(db).def_map(db);
+                let def_map = self.crate_root().def_map(db);
                 def_map[Self::ROOT].scope.get(name)
             }
             None => self[Self::ROOT].scope.get(name),
         };
         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))
         };