Skip to content

Commit 762d293

Browse files
Apply the proposed refactoring
1 parent 7a2e449 commit 762d293

File tree

1 file changed

+43
-38
lines changed

1 file changed

+43
-38
lines changed

crates/ra_hir_def/src/find_path.rs

Lines changed: 43 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,34 @@ use hir_expand::name::{known, Name};
1111

1212
const MAX_PATH_LEN: usize = 15;
1313

14+
impl ModPath {
15+
fn starts_with_std(&self) -> bool {
16+
self.segments.first().filter(|&first_segment| first_segment == &known::std).is_some()
17+
}
18+
19+
// When std library is present, paths starting with `std::`
20+
// should be preferred over paths starting with `core::` and `alloc::`
21+
fn should_start_with_std(&self) -> bool {
22+
self.segments
23+
.first()
24+
.filter(|&first_segment| {
25+
first_segment == &known::alloc || first_segment == &known::core
26+
})
27+
.is_some()
28+
}
29+
30+
fn len(&self) -> usize {
31+
self.segments.len()
32+
+ match self.kind {
33+
PathKind::Plain => 0,
34+
PathKind::Super(i) => i as usize,
35+
PathKind::Crate => 1,
36+
PathKind::Abs => 0,
37+
PathKind::DollarCrate(_) => 1,
38+
}
39+
}
40+
}
41+
1442
// FIXME: handle local items
1543

1644
/// Find a path that can be used to refer to a certain item. This can depend on
@@ -102,7 +130,7 @@ fn find_path_inner(
102130
let mut best_path = None;
103131
let mut best_path_len = max_len;
104132
for (module_id, name) in importable_locations {
105-
let mut new_path = match find_path_inner(
133+
let mut path = match find_path_inner(
106134
db,
107135
ItemInNs::Types(ModuleDefId::ModuleId(module_id)),
108136
from,
@@ -111,51 +139,28 @@ fn find_path_inner(
111139
None => continue,
112140
Some(path) => path,
113141
};
114-
new_path.segments.push(name);
142+
path.segments.push(name);
115143

116-
if prefer_new_path(best_path_len, best_path.as_ref(), &new_path) {
117-
best_path_len = path_len(&new_path);
118-
best_path = Some(new_path);
119-
}
144+
let new_path =
145+
if let Some(best_path) = best_path { select_best_path(best_path, path) } else { path };
146+
best_path_len = new_path.len();
147+
best_path = Some(new_path);
120148
}
121149
best_path
122150
}
123151

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,
152+
fn select_best_path(old_path: ModPath, new_path: ModPath) -> ModPath {
153+
if old_path.starts_with_std() && new_path.should_start_with_std() {
154+
old_path
155+
} else if new_path.starts_with_std() && old_path.should_start_with_std() {
156+
new_path
157+
} else if new_path.len() < old_path.len() {
158+
new_path
159+
} else {
160+
old_path
139161
}
140162
}
141163

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-
148-
fn path_len(path: &ModPath) -> usize {
149-
path.segments.len()
150-
+ match path.kind {
151-
PathKind::Plain => 0,
152-
PathKind::Super(i) => i as usize,
153-
PathKind::Crate => 1,
154-
PathKind::Abs => 0,
155-
PathKind::DollarCrate(_) => 1,
156-
}
157-
}
158-
159164
fn find_importable_locations(
160165
db: &impl DefDatabase,
161166
item: ItemInNs,

0 commit comments

Comments
 (0)