aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_def
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_def')
-rw-r--r--crates/hir_def/src/find_path.rs2
-rw-r--r--crates/hir_def/src/import_map.rs36
-rw-r--r--crates/hir_def/src/path.rs22
3 files changed, 29 insertions, 31 deletions
diff --git a/crates/hir_def/src/find_path.rs b/crates/hir_def/src/find_path.rs
index 9106ed45f..02613c4c4 100644
--- a/crates/hir_def/src/find_path.rs
+++ b/crates/hir_def/src/find_path.rs
@@ -222,6 +222,7 @@ fn find_path_inner(
222 best_path_len - 1, 222 best_path_len - 1,
223 prefixed, 223 prefixed,
224 )?; 224 )?;
225 mark::hit!(partially_imported);
225 path.segments.push(info.path.segments.last().unwrap().clone()); 226 path.segments.push(info.path.segments.last().unwrap().clone());
226 Some(path) 227 Some(path)
227 }) 228 })
@@ -515,6 +516,7 @@ mod tests {
515 516
516 #[test] 517 #[test]
517 fn partially_imported() { 518 fn partially_imported() {
519 mark::check!(partially_imported);
518 // Tests that short paths are used even for external items, when parts of the path are 520 // Tests that short paths are used even for external items, when parts of the path are
519 // already in scope. 521 // already in scope.
520 let code = r#" 522 let code = r#"
diff --git a/crates/hir_def/src/import_map.rs b/crates/hir_def/src/import_map.rs
index 44bfe1593..028cae2e7 100644
--- a/crates/hir_def/src/import_map.rs
+++ b/crates/hir_def/src/import_map.rs
@@ -4,17 +4,16 @@ use std::{cmp::Ordering, fmt, hash::BuildHasherDefault, sync::Arc};
4 4
5use base_db::CrateId; 5use base_db::CrateId;
6use fst::{self, Streamer}; 6use fst::{self, Streamer};
7use hir_expand::name::Name;
7use indexmap::{map::Entry, IndexMap}; 8use indexmap::{map::Entry, IndexMap};
9use itertools::Itertools;
8use rustc_hash::{FxHashMap, FxHasher}; 10use rustc_hash::{FxHashMap, FxHasher};
9use smallvec::SmallVec; 11use smallvec::SmallVec;
10use syntax::SmolStr; 12use syntax::SmolStr;
11 13
12use crate::{ 14use crate::{
13 db::DefDatabase, 15 db::DefDatabase, item_scope::ItemInNs, visibility::Visibility, AssocItemId, ModuleDefId,
14 item_scope::ItemInNs, 16 ModuleId, TraitId,
15 path::{ModPath, PathKind},
16 visibility::Visibility,
17 AssocItemId, ModuleDefId, ModuleId, TraitId,
18}; 17};
19 18
20type FxIndexMap<K, V> = IndexMap<K, V, BuildHasherDefault<FxHasher>>; 19type FxIndexMap<K, V> = IndexMap<K, V, BuildHasherDefault<FxHasher>>;
@@ -23,11 +22,28 @@ type FxIndexMap<K, V> = IndexMap<K, V, BuildHasherDefault<FxHasher>>;
23#[derive(Debug, Clone, Eq, PartialEq)] 22#[derive(Debug, Clone, Eq, PartialEq)]
24pub struct ImportInfo { 23pub struct ImportInfo {
25 /// A path that can be used to import the item, relative to the crate's root. 24 /// A path that can be used to import the item, relative to the crate's root.
26 pub path: ModPath, 25 pub path: ImportPath,
27 /// The module containing this item. 26 /// The module containing this item.
28 pub container: ModuleId, 27 pub container: ModuleId,
29} 28}
30 29
30#[derive(Debug, Clone, Eq, PartialEq)]
31pub struct ImportPath {
32 pub segments: Vec<Name>,
33}
34
35impl fmt::Display for ImportPath {
36 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
37 fmt::Display::fmt(&self.segments.iter().format("::"), f)
38 }
39}
40
41impl ImportPath {
42 fn len(&self) -> usize {
43 self.segments.len()
44 }
45}
46
31/// A map from publicly exported items to the path needed to import/name them from a downstream 47/// A map from publicly exported items to the path needed to import/name them from a downstream
32/// crate. 48/// crate.
33/// 49///
@@ -61,7 +77,7 @@ impl ImportMap {
61 let mut import_map = Self::default(); 77 let mut import_map = Self::default();
62 78
63 // We look only into modules that are public(ly reexported), starting with the crate root. 79 // We look only into modules that are public(ly reexported), starting with the crate root.
64 let empty = ModPath { kind: PathKind::Plain, segments: vec![] }; 80 let empty = ImportPath { segments: vec![] };
65 let root = ModuleId { krate, local_id: def_map.root }; 81 let root = ModuleId { krate, local_id: def_map.root };
66 let mut worklist = vec![(root, empty)]; 82 let mut worklist = vec![(root, empty)];
67 while let Some((module, mod_path)) = worklist.pop() { 83 while let Some((module, mod_path)) = worklist.pop() {
@@ -152,8 +168,8 @@ impl ImportMap {
152 } 168 }
153 169
154 /// Returns the `ModPath` needed to import/mention `item`, relative to this crate's root. 170 /// Returns the `ModPath` needed to import/mention `item`, relative to this crate's root.
155 pub fn path_of(&self, item: ItemInNs) -> Option<&ModPath> { 171 pub fn path_of(&self, item: ItemInNs) -> Option<&ImportPath> {
156 Some(&self.map.get(&item)?.path) 172 self.import_info_for(item).map(|it| &it.path)
157 } 173 }
158 174
159 pub fn import_info_for(&self, item: ItemInNs) -> Option<&ImportInfo> { 175 pub fn import_info_for(&self, item: ItemInNs) -> Option<&ImportInfo> {
@@ -197,7 +213,7 @@ impl fmt::Debug for ImportMap {
197 } 213 }
198} 214}
199 215
200fn fst_path(path: &ModPath) -> String { 216fn fst_path(path: &ImportPath) -> String {
201 let mut s = path.to_string(); 217 let mut s = path.to_string();
202 s.make_ascii_lowercase(); 218 s.make_ascii_lowercase();
203 s 219 s
diff --git a/crates/hir_def/src/path.rs b/crates/hir_def/src/path.rs
index 209b18e78..5b8c1e449 100644
--- a/crates/hir_def/src/path.rs
+++ b/crates/hir_def/src/path.rs
@@ -13,7 +13,7 @@ use hir_expand::{
13 hygiene::Hygiene, 13 hygiene::Hygiene,
14 name::{AsName, Name}, 14 name::{AsName, Name},
15}; 15};
16use syntax::ast::{self, make}; 16use syntax::ast::{self};
17 17
18use crate::{ 18use crate::{
19 type_ref::{TypeBound, TypeRef}, 19 type_ref::{TypeBound, TypeRef},
@@ -100,26 +100,6 @@ impl ModPath {
100 } 100 }
101 self.segments.first() 101 self.segments.first()
102 } 102 }
103
104 pub fn to_ast_path(&self) -> ast::Path {
105 let mut segments = Vec::new();
106 let mut is_abs = false;
107 match self.kind {
108 PathKind::Plain => {}
109 PathKind::Super(0) => segments.push(make::path_segment_self()),
110 PathKind::Super(n) => segments.extend((0..n).map(|_| make::path_segment_super())),
111 PathKind::Crate => segments.push(make::path_segment_crate()),
112 PathKind::Abs => is_abs = true,
113 PathKind::DollarCrate(_) => (),
114 }
115
116 segments.extend(
117 self.segments
118 .iter()
119 .map(|segment| make::path_segment(make::name_ref(&segment.to_string()))),
120 );
121 make::path_from_segments(segments, is_abs)
122 }
123} 103}
124 104
125#[derive(Debug, Clone, PartialEq, Eq, Hash)] 105#[derive(Debug, Clone, PartialEq, Eq, Hash)]