diff options
Diffstat (limited to 'crates/hir_def')
-rw-r--r-- | crates/hir_def/src/find_path.rs | 2 | ||||
-rw-r--r-- | crates/hir_def/src/import_map.rs | 36 | ||||
-rw-r--r-- | crates/hir_def/src/path.rs | 22 |
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 | ||
5 | use base_db::CrateId; | 5 | use base_db::CrateId; |
6 | use fst::{self, Streamer}; | 6 | use fst::{self, Streamer}; |
7 | use hir_expand::name::Name; | ||
7 | use indexmap::{map::Entry, IndexMap}; | 8 | use indexmap::{map::Entry, IndexMap}; |
9 | use itertools::Itertools; | ||
8 | use rustc_hash::{FxHashMap, FxHasher}; | 10 | use rustc_hash::{FxHashMap, FxHasher}; |
9 | use smallvec::SmallVec; | 11 | use smallvec::SmallVec; |
10 | use syntax::SmolStr; | 12 | use syntax::SmolStr; |
11 | 13 | ||
12 | use crate::{ | 14 | use 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 | ||
20 | type FxIndexMap<K, V> = IndexMap<K, V, BuildHasherDefault<FxHasher>>; | 19 | type 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)] |
24 | pub struct ImportInfo { | 23 | pub 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)] | ||
31 | pub struct ImportPath { | ||
32 | pub segments: Vec<Name>, | ||
33 | } | ||
34 | |||
35 | impl 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 | |||
41 | impl 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 | ||
200 | fn fst_path(path: &ModPath) -> String { | 216 | fn 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 | }; |
16 | use syntax::ast::{self, make}; | 16 | use syntax::ast::{self}; |
17 | 17 | ||
18 | use crate::{ | 18 | use 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)] |