diff options
Diffstat (limited to 'crates/ra_hir_def/src')
-rw-r--r-- | crates/ra_hir_def/src/find_path.rs | 37 |
1 files changed, 31 insertions, 6 deletions
diff --git a/crates/ra_hir_def/src/find_path.rs b/crates/ra_hir_def/src/find_path.rs index 8cc2fb160..d9e67607f 100644 --- a/crates/ra_hir_def/src/find_path.rs +++ b/crates/ra_hir_def/src/find_path.rs | |||
@@ -7,7 +7,7 @@ use crate::{ | |||
7 | visibility::Visibility, | 7 | visibility::Visibility, |
8 | CrateId, ModuleDefId, ModuleId, | 8 | CrateId, ModuleDefId, ModuleId, |
9 | }; | 9 | }; |
10 | use hir_expand::name::Name; | 10 | use hir_expand::name::{known, Name}; |
11 | 11 | ||
12 | const MAX_PATH_LEN: usize = 15; | 12 | const MAX_PATH_LEN: usize = 15; |
13 | 13 | ||
@@ -102,7 +102,7 @@ fn find_path_inner( | |||
102 | let mut best_path = None; | 102 | let mut best_path = None; |
103 | let mut best_path_len = max_len; | 103 | let mut best_path_len = max_len; |
104 | for (module_id, name) in importable_locations { | 104 | for (module_id, name) in importable_locations { |
105 | let mut path = match find_path_inner( | 105 | let mut new_path = match find_path_inner( |
106 | db, | 106 | db, |
107 | ItemInNs::Types(ModuleDefId::ModuleId(module_id)), | 107 | ItemInNs::Types(ModuleDefId::ModuleId(module_id)), |
108 | from, | 108 | from, |
@@ -111,15 +111,40 @@ fn find_path_inner( | |||
111 | None => continue, | 111 | None => continue, |
112 | Some(path) => path, | 112 | Some(path) => path, |
113 | }; | 113 | }; |
114 | path.segments.push(name); | 114 | new_path.segments.push(name); |
115 | if path_len(&path) < best_path_len { | 115 | |
116 | best_path_len = path_len(&path); | 116 | if prefer_new_path(best_path_len, best_path.as_ref(), &new_path) { |
117 | best_path = Some(path); | 117 | best_path_len = path_len(&new_path); |
118 | best_path = Some(new_path); | ||
118 | } | 119 | } |
119 | } | 120 | } |
120 | best_path | 121 | best_path |
121 | } | 122 | } |
122 | 123 | ||
124 | fn prefer_new_path(old_path_len: usize, old_path: Option<&ModPath>, new_path: &ModPath) -> bool { | ||
125 | match (old_path.and_then(|mod_path| mod_path.segments.first()), new_path.segments.first()) { | ||
126 | (Some(old_path_start), Some(new_path_start)) | ||
127 | if old_path_start == &known::std && use_std_instead(new_path_start) => | ||
128 | { | ||
129 | false | ||
130 | } | ||
131 | (Some(old_path_start), Some(new_path_start)) | ||
132 | if new_path_start == &known::std && use_std_instead(old_path_start) => | ||
133 | { | ||
134 | true | ||
135 | } | ||
136 | (None, Some(_)) => true, | ||
137 | (Some(_), None) => false, | ||
138 | _ => path_len(new_path) < old_path_len, | ||
139 | } | ||
140 | } | ||
141 | |||
142 | // When std library is present, paths starting with `std::` | ||
143 | // should be preferred over paths starting with `core::` and `alloc::` | ||
144 | fn use_std_instead(name: &Name) -> bool { | ||
145 | name == &known::core || name == &known::alloc | ||
146 | } | ||
147 | |||
123 | fn path_len(path: &ModPath) -> usize { | 148 | fn path_len(path: &ModPath) -> usize { |
124 | path.segments.len() | 149 | path.segments.len() |
125 | + match path.kind { | 150 | + match path.kind { |