about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2022-08-15 14:49:12 +0000
committerbors <bors@rust-lang.org>2022-08-15 14:49:12 +0000
commit3561433ef2ee6eff86b99be4d9e59114c7f0f875 (patch)
treeb1bb4173fd30fa4c404fc024bbfd74ad9dbe62c0
parent6d6201299c72fb3c7b2d7c647623ad12d7886612 (diff)
parent88b19cc39b14446cc12e02a20c6f489f9883b760 (diff)
downloadrust-3561433ef2ee6eff86b99be4d9e59114c7f0f875.tar.gz
rust-3561433ef2ee6eff86b99be4d9e59114c7f0f875.zip
Auto merge of #13026 - Veykril:nameres, r=Veykril
internal: Make `resolve_name_in_module` a bit more lazy
-rw-r--r--crates/hir-def/src/nameres/path_resolution.rs32
-rw-r--r--crates/hir-def/src/per_ns.rs12
2 files changed, 28 insertions, 16 deletions
diff --git a/crates/hir-def/src/nameres/path_resolution.rs b/crates/hir-def/src/nameres/path_resolution.rs
index c579bc9194c..8dfda6df64e 100644
--- a/crates/hir-def/src/nameres/path_resolution.rs
+++ b/crates/hir-def/src/nameres/path_resolution.rs
@@ -399,14 +399,15 @@ impl DefMap {
                 Some(_) | None => from_scope.or(from_builtin),
             },
         };
-        let from_extern_prelude = self
-            .extern_prelude
-            .get(name)
-            .map_or(PerNs::none(), |&it| PerNs::types(it.into(), Visibility::Public));
 
-        let from_prelude = self.resolve_in_prelude(db, name);
+        let extern_prelude = || {
+            self.extern_prelude
+                .get(name)
+                .map_or(PerNs::none(), |&it| PerNs::types(it.into(), Visibility::Public))
+        };
+        let prelude = || self.resolve_in_prelude(db, name);
 
-        from_legacy_macro.or(from_scope_or_builtin).or(from_extern_prelude).or(from_prelude)
+        from_legacy_macro.or(from_scope_or_builtin).or_else(extern_prelude).or_else(prelude)
     }
 
     fn resolve_name_in_crate_root_or_extern_prelude(
@@ -414,20 +415,19 @@ impl DefMap {
         db: &dyn DefDatabase,
         name: &Name,
     ) -> PerNs {
-        let arc;
-        let crate_def_map = match self.block {
+        let from_crate_root = match self.block {
             Some(_) => {
-                arc = self.crate_root(db).def_map(db);
-                &arc
+                let def_map = self.crate_root(db).def_map(db);
+                def_map[def_map.root].scope.get(name)
             }
-            None => self,
+            None => self[self.root].scope.get(name),
+        };
+        let from_extern_prelude = || {
+            self.resolve_name_in_extern_prelude(db, name)
+                .map_or(PerNs::none(), |it| PerNs::types(it.into(), Visibility::Public))
         };
-        let from_crate_root = crate_def_map[crate_def_map.root].scope.get(name);
-        let from_extern_prelude = self
-            .resolve_name_in_extern_prelude(db, name)
-            .map_or(PerNs::none(), |it| PerNs::types(it.into(), Visibility::Public));
 
-        from_crate_root.or(from_extern_prelude)
+        from_crate_root.or_else(from_extern_prelude)
     }
 
     fn resolve_in_prelude(&self, db: &dyn DefDatabase, name: &Name) -> PerNs {
diff --git a/crates/hir-def/src/per_ns.rs b/crates/hir-def/src/per_ns.rs
index bf5bf10c4ca..2bc1f8e926e 100644
--- a/crates/hir-def/src/per_ns.rs
+++ b/crates/hir-def/src/per_ns.rs
@@ -43,6 +43,10 @@ impl PerNs {
         self.types.is_none() && self.values.is_none() && self.macros.is_none()
     }
 
+    pub fn is_full(&self) -> bool {
+        self.types.is_some() && self.values.is_some() && self.macros.is_some()
+    }
+
     pub fn take_types(self) -> Option<ModuleDefId> {
         self.types.map(|it| it.0)
     }
@@ -84,6 +88,14 @@ impl PerNs {
         }
     }
 
+    pub fn or_else(self, f: impl FnOnce() -> PerNs) -> PerNs {
+        if self.is_full() {
+            self
+        } else {
+            self.or(f())
+        }
+    }
+
     pub fn iter_items(self) -> impl Iterator<Item = ItemInNs> {
         let _p = profile::span("PerNs::iter_items");
         self.types