Skip to content

Commit 3bdf2e0

Browse files
Merge #2917
2917: Prefer imports starting with std r=matklad a=SomeoneToIgnore Closes #2915 Co-authored-by: Kirill Bulatov <[email protected]>
2 parents 50b6a98 + 713870e commit 3bdf2e0

File tree

3 files changed

+88
-14
lines changed

3 files changed

+88
-14
lines changed

crates/ra_hir_def/src/find_path.rs

Lines changed: 85 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,39 @@ use crate::{
77
visibility::Visibility,
88
CrateId, ModuleDefId, ModuleId,
99
};
10-
use hir_expand::name::Name;
10+
use hir_expand::name::{known, Name};
11+
use test_utils::tested_by;
1112

1213
const MAX_PATH_LEN: usize = 15;
1314

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

1645
/// Find a path that can be used to refer to a certain item. This can depend on
@@ -112,23 +141,27 @@ fn find_path_inner(
112141
Some(path) => path,
113142
};
114143
path.segments.push(name);
115-
if path_len(&path) < best_path_len {
116-
best_path_len = path_len(&path);
117-
best_path = Some(path);
118-
}
144+
145+
let new_path =
146+
if let Some(best_path) = best_path { select_best_path(best_path, path) } else { path };
147+
best_path_len = new_path.len();
148+
best_path = Some(new_path);
119149
}
120150
best_path
121151
}
122152

123-
fn path_len(path: &ModPath) -> usize {
124-
path.segments.len()
125-
+ match path.kind {
126-
PathKind::Plain => 0,
127-
PathKind::Super(i) => i as usize,
128-
PathKind::Crate => 1,
129-
PathKind::Abs => 0,
130-
PathKind::DollarCrate(_) => 1,
131-
}
153+
fn select_best_path(old_path: ModPath, new_path: ModPath) -> ModPath {
154+
if old_path.starts_with_std() && new_path.should_start_with_std() {
155+
tested_by!(prefer_std_paths);
156+
old_path
157+
} else if new_path.starts_with_std() && old_path.should_start_with_std() {
158+
tested_by!(prefer_std_paths);
159+
new_path
160+
} else if new_path.len() < old_path.len() {
161+
new_path
162+
} else {
163+
old_path
164+
}
132165
}
133166

134167
fn find_importable_locations(
@@ -201,6 +234,7 @@ mod tests {
201234
use hir_expand::hygiene::Hygiene;
202235
use ra_db::fixture::WithFixture;
203236
use ra_syntax::ast::AstNode;
237+
use test_utils::covers;
204238

205239
/// `code` needs to contain a cursor marker; checks that `find_path` for the
206240
/// item the `path` refers to returns that same path when called from the
@@ -452,4 +486,41 @@ mod tests {
452486
"#;
453487
check_found_path(code, "crate::foo::S");
454488
}
489+
490+
#[test]
491+
fn prefer_std_paths_over_alloc() {
492+
covers!(prefer_std_paths);
493+
let code = r#"
494+
//- /main.rs crate:main deps:alloc,std
495+
<|>
496+
497+
//- /std.rs crate:std deps:alloc
498+
pub mod sync {
499+
pub use alloc::sync::Arc;
500+
}
501+
502+
//- /zzz.rs crate:alloc
503+
pub mod sync {
504+
pub struct Arc;
505+
}
506+
"#;
507+
check_found_path(code, "std::sync::Arc");
508+
}
509+
510+
#[test]
511+
fn prefer_shorter_paths_if_not_alloc() {
512+
let code = r#"
513+
//- /main.rs crate:main deps:megaalloc,std
514+
<|>
515+
516+
//- /std.rs crate:std deps:megaalloc
517+
pub mod sync {
518+
pub use megaalloc::sync::Arc;
519+
}
520+
521+
//- /zzz.rs crate:megaalloc
522+
pub struct Arc;
523+
"#;
524+
check_found_path(code, "megaalloc::Arc");
525+
}
455526
}

crates/ra_hir_def/src/marks.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,5 @@ test_utils::marks!(
1313
macro_dollar_crate_self
1414
macro_dollar_crate_other
1515
infer_resolve_while_let
16+
prefer_std_paths
1617
);

crates/ra_hir_expand/src/name.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,8 @@ pub mod known {
141141
macro_rules,
142142
// Components of known path (value or mod name)
143143
std,
144+
core,
145+
alloc,
144146
iter,
145147
ops,
146148
future,

0 commit comments

Comments
 (0)