]> git.lizzy.rs Git - rust.git/commitdiff
Constrain ImportMap to only store simple paths
authorAleksey Kladov <aleksey.kladov@gmail.com>
Tue, 6 Oct 2020 15:04:29 +0000 (17:04 +0200)
committerAleksey Kladov <aleksey.kladov@gmail.com>
Tue, 6 Oct 2020 15:04:29 +0000 (17:04 +0200)
crates/hir_def/src/import_map.rs

index 44bfe15934aa0dcc3b2d36fc148a3baaa7826c7a..028cae2e7229b88105c6b7d47317564ba03cc85b 100644 (file)
@@ -4,17 +4,16 @@
 
 use base_db::CrateId;
 use fst::{self, Streamer};
+use hir_expand::name::Name;
 use indexmap::{map::Entry, IndexMap};
+use itertools::Itertools;
 use rustc_hash::{FxHashMap, FxHasher};
 use smallvec::SmallVec;
 use syntax::SmolStr;
 
 use crate::{
-    db::DefDatabase,
-    item_scope::ItemInNs,
-    path::{ModPath, PathKind},
-    visibility::Visibility,
-    AssocItemId, ModuleDefId, ModuleId, TraitId,
+    db::DefDatabase, item_scope::ItemInNs, visibility::Visibility, AssocItemId, ModuleDefId,
+    ModuleId, TraitId,
 };
 
 type FxIndexMap<K, V> = IndexMap<K, V, BuildHasherDefault<FxHasher>>;
 #[derive(Debug, Clone, Eq, PartialEq)]
 pub struct ImportInfo {
     /// A path that can be used to import the item, relative to the crate's root.
-    pub path: ModPath,
+    pub path: ImportPath,
     /// The module containing this item.
     pub container: ModuleId,
 }
 
+#[derive(Debug, Clone, Eq, PartialEq)]
+pub struct ImportPath {
+    pub segments: Vec<Name>,
+}
+
+impl fmt::Display for ImportPath {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        fmt::Display::fmt(&self.segments.iter().format("::"), f)
+    }
+}
+
+impl ImportPath {
+    fn len(&self) -> usize {
+        self.segments.len()
+    }
+}
+
 /// A map from publicly exported items to the path needed to import/name them from a downstream
 /// crate.
 ///
@@ -61,7 +77,7 @@ pub fn import_map_query(db: &dyn DefDatabase, krate: CrateId) -> Arc<Self> {
         let mut import_map = Self::default();
 
         // We look only into modules that are public(ly reexported), starting with the crate root.
-        let empty = ModPath { kind: PathKind::Plain, segments: vec![] };
+        let empty = ImportPath { segments: vec![] };
         let root = ModuleId { krate, local_id: def_map.root };
         let mut worklist = vec![(root, empty)];
         while let Some((module, mod_path)) = worklist.pop() {
@@ -152,8 +168,8 @@ pub fn import_map_query(db: &dyn DefDatabase, krate: CrateId) -> Arc<Self> {
     }
 
     /// Returns the `ModPath` needed to import/mention `item`, relative to this crate's root.
-    pub fn path_of(&self, item: ItemInNs) -> Option<&ModPath> {
-        Some(&self.map.get(&item)?.path)
+    pub fn path_of(&self, item: ItemInNs) -> Option<&ImportPath> {
+        self.import_info_for(item).map(|it| &it.path)
     }
 
     pub fn import_info_for(&self, item: ItemInNs) -> Option<&ImportInfo> {
@@ -197,7 +213,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
     }
 }
 
-fn fst_path(path: &ModPath) -> String {
+fn fst_path(path: &ImportPath) -> String {
     let mut s = path.to_string();
     s.make_ascii_lowercase();
     s