about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRyo Yoshida <low.ryoshida@gmail.com>2023-06-30 23:35:32 +0900
committerRyo Yoshida <low.ryoshida@gmail.com>2023-07-01 00:18:23 +0900
commit5db0e1a34630b05d19308008d5139b1ff170d69e (patch)
treefc6fed34ca1ace3dbe2cae330b6c70037af6858f
parent2b106648a75f2d76b817b9411a8449d2a79f5283 (diff)
downloadrust-5db0e1a34630b05d19308008d5139b1ff170d69e.tar.gz
rust-5db0e1a34630b05d19308008d5139b1ff170d69e.zip
Restructure `ImportMap` collection
-rw-r--r--crates/hir-def/src/import_map.rs97
1 files changed, 50 insertions, 47 deletions
diff --git a/crates/hir-def/src/import_map.rs b/crates/hir-def/src/import_map.rs
index 63caaa8f831..d742b2eef0a 100644
--- a/crates/hir-def/src/import_map.rs
+++ b/crates/hir-def/src/import_map.rs
@@ -53,13 +53,12 @@ impl ImportMap {
     pub(crate) fn import_map_query(db: &dyn DefDatabase, krate: CrateId) -> Arc<Self> {
         let _p = profile::span("import_map_query");
 
-        let mut import_map = collect_import_map(db, krate);
+        let map = collect_import_map(db, krate);
 
-        let mut importables: Vec<_> = import_map
-            .map
+        let mut importables: Vec<_> = map
             .iter()
             // We've only collected items, whose name cannot be tuple field.
-            .map(|(item, info)| (item, info.name.as_str().unwrap().to_ascii_lowercase()))
+            .map(|(&item, info)| (item, info.name.as_str().unwrap().to_ascii_lowercase()))
             .collect();
         importables.sort_by(|(_, lhs_name), (_, rhs_name)| lhs_name.cmp(rhs_name));
 
@@ -70,61 +69,30 @@ impl ImportMap {
             let _ = builder.insert(name, start_idx as u64);
         }
 
-        import_map.fst = builder.into_map();
-        import_map.importables = importables.into_iter().map(|(&item, _)| item).collect();
-
-        Arc::new(import_map)
+        Arc::new(ImportMap {
+            map,
+            fst: builder.into_map(),
+            importables: importables.into_iter().map(|(item, _)| item).collect(),
+        })
     }
 
     pub fn import_info_for(&self, item: ItemInNs) -> Option<&ImportInfo> {
         self.map.get(&item)
     }
-
-    fn collect_trait_assoc_items(
-        &mut self,
-        db: &dyn DefDatabase,
-        tr: TraitId,
-        is_type_in_ns: bool,
-        trait_import_info: &ImportInfo,
-    ) {
-        let _p = profile::span("collect_trait_assoc_items");
-        for (assoc_item_name, item) in &db.trait_data(tr).items {
-            let module_def_id = match item {
-                AssocItemId::FunctionId(f) => ModuleDefId::from(*f),
-                AssocItemId::ConstId(c) => ModuleDefId::from(*c),
-                // cannot use associated type aliases directly: need a `<Struct as Trait>::TypeAlias`
-                // qualifier, ergo no need to store it for imports in import_map
-                AssocItemId::TypeAliasId(_) => {
-                    cov_mark::hit!(type_aliases_ignored);
-                    continue;
-                }
-            };
-            let assoc_item = if is_type_in_ns {
-                ItemInNs::Types(module_def_id)
-            } else {
-                ItemInNs::Values(module_def_id)
-            };
-
-            let assoc_item_info = ImportInfo {
-                container: trait_import_info.container,
-                name: assoc_item_name.clone(),
-                is_trait_assoc_item: true,
-            };
-            self.map.insert(assoc_item, assoc_item_info);
-        }
-    }
 }
 
-fn collect_import_map(db: &dyn DefDatabase, krate: CrateId) -> ImportMap {
+fn collect_import_map(db: &dyn DefDatabase, krate: CrateId) -> FxIndexMap<ItemInNs, ImportInfo> {
     let _p = profile::span("collect_import_map");
 
     let def_map = db.crate_def_map(krate);
-    let mut import_map = ImportMap::default();
+    let mut map = FxIndexMap::default();
 
     // We look only into modules that are public(ly reexported), starting with the crate root.
     let root = def_map.module_id(DefMap::ROOT);
     let mut worklist = vec![(root, 0)];
+    // Records items' minimum module depth.
     let mut depth_map = FxHashMap::default();
+
     while let Some((module, depth)) = worklist.pop() {
         let ext_def_map;
         let mod_data = if module.krate == krate {
@@ -166,15 +134,16 @@ fn collect_import_map(db: &dyn DefDatabase, krate: CrateId) -> ImportMap {
                 }
 
                 if let Some(ModuleDefId::TraitId(tr)) = item.as_module_def_id() {
-                    import_map.collect_trait_assoc_items(
+                    collect_trait_assoc_items(
                         db,
+                        &mut map,
                         tr,
                         matches!(item, ItemInNs::Types(_)),
                         &import_info,
                     );
                 }
 
-                import_map.map.insert(item, import_info);
+                map.insert(item, import_info);
 
                 // If we've just added a module, descend into it. We might traverse modules
                 // multiple times, but only if the module depth is smaller (else we `continue`
@@ -186,7 +155,41 @@ fn collect_import_map(db: &dyn DefDatabase, krate: CrateId) -> ImportMap {
         }
     }
 
-    import_map
+    map
+}
+
+fn collect_trait_assoc_items(
+    db: &dyn DefDatabase,
+    map: &mut FxIndexMap<ItemInNs, ImportInfo>,
+    tr: TraitId,
+    is_type_in_ns: bool,
+    trait_import_info: &ImportInfo,
+) {
+    let _p = profile::span("collect_trait_assoc_items");
+    for (assoc_item_name, item) in &db.trait_data(tr).items {
+        let module_def_id = match item {
+            AssocItemId::FunctionId(f) => ModuleDefId::from(*f),
+            AssocItemId::ConstId(c) => ModuleDefId::from(*c),
+            // cannot use associated type aliases directly: need a `<Struct as Trait>::TypeAlias`
+            // qualifier, ergo no need to store it for imports in import_map
+            AssocItemId::TypeAliasId(_) => {
+                cov_mark::hit!(type_aliases_ignored);
+                continue;
+            }
+        };
+        let assoc_item = if is_type_in_ns {
+            ItemInNs::Types(module_def_id)
+        } else {
+            ItemInNs::Values(module_def_id)
+        };
+
+        let assoc_item_info = ImportInfo {
+            container: trait_import_info.container,
+            name: assoc_item_name.clone(),
+            is_trait_assoc_item: true,
+        };
+        map.insert(assoc_item, assoc_item_info);
+    }
 }
 
 impl PartialEq for ImportMap {