Skip to content

Commit 7a7eb69

Browse files
authored
Merge pull request rust-lang#19023 from Wilfred/sequence_type_names
minor: Suggest better names when a type is a sequence
2 parents 165d78a + fff24d5 commit 7a7eb69

File tree

2 files changed

+93
-10
lines changed

2 files changed

+93
-10
lines changed

src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_variable.rs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1672,8 +1672,8 @@ macro_rules! vec {
16721672
() => {Vec}
16731673
}
16741674
fn main() {
1675-
let $0vec = vec![];
1676-
let _ = vec;
1675+
let $0items = vec![];
1676+
let _ = items;
16771677
}
16781678
"#,
16791679
"Extract into variable",
@@ -1696,8 +1696,8 @@ macro_rules! vec {
16961696
() => {Vec}
16971697
}
16981698
fn main() {
1699-
const $0VEC: Vec = vec![];
1700-
let _ = VEC;
1699+
const $0ITEMS: Vec = vec![];
1700+
let _ = ITEMS;
17011701
}
17021702
"#,
17031703
"Extract into constant",
@@ -1720,8 +1720,8 @@ macro_rules! vec {
17201720
() => {Vec}
17211721
}
17221722
fn main() {
1723-
static $0VEC: Vec = vec![];
1724-
let _ = VEC;
1723+
static $0ITEMS: Vec = vec![];
1724+
let _ = ITEMS;
17251725
}
17261726
"#,
17271727
"Extract into static",
@@ -2019,8 +2019,8 @@ impl<T> Vec<T> {
20192019
}
20202020
20212021
fn foo(s: &mut S) {
2022-
let $0vec = &mut s.vec;
2023-
vec.push(0);
2022+
let $0items = &mut s.vec;
2023+
items.push(0);
20242024
}"#,
20252025
"Extract into variable",
20262026
);
@@ -2106,8 +2106,8 @@ impl<T> Vec<T> {
21062106
}
21072107
21082108
fn foo(f: &mut Y) {
2109-
let $0vec = &mut f.field.field.vec;
2110-
vec.push(0);
2109+
let $0items = &mut f.field.field.vec;
2110+
items.push(0);
21112111
}"#,
21122112
"Extract into variable",
21132113
);

src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/suggest_name.rs

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,12 @@ const USELESS_NAME_PREFIXES: &[&str] = &["from_", "with_", "into_"];
3131
/// `Result<User, Error>` -> `User`
3232
const WRAPPER_TYPES: &[&str] = &["Box", "Arc", "Rc", "Option", "Result"];
3333

34+
/// Generic types replaced by a plural of their first argument.
35+
///
36+
/// # Examples
37+
/// `Vec<Name>` -> "names"
38+
const SEQUENCE_TYPES: &[&str] = &["Vec", "VecDeque", "LinkedList"];
39+
3440
/// Prefixes to strip from methods names
3541
///
3642
/// # Examples
@@ -378,6 +384,11 @@ fn name_of_type(ty: &hir::Type, db: &RootDatabase, edition: Edition) -> Option<S
378384
return name_of_type(&inner_ty, db, edition);
379385
}
380386

387+
if SEQUENCE_TYPES.contains(&name.as_str()) {
388+
let inner_ty = ty.type_arguments().next();
389+
return Some(sequence_name(inner_ty.as_ref(), db, edition));
390+
}
391+
381392
name
382393
} else if let Some(trait_) = ty.as_dyn_trait() {
383394
trait_name(&trait_, db, edition)?
@@ -390,12 +401,32 @@ fn name_of_type(ty: &hir::Type, db: &RootDatabase, edition: Edition) -> Option<S
390401
name
391402
} else if let Some(inner_ty) = ty.remove_ref() {
392403
return name_of_type(&inner_ty, db, edition);
404+
} else if let Some(inner_ty) = ty.as_slice() {
405+
return Some(sequence_name(Some(&inner_ty), db, edition));
393406
} else {
394407
return None;
395408
};
396409
normalize(&name)
397410
}
398411

412+
fn sequence_name(inner_ty: Option<&hir::Type>, db: &RootDatabase, edition: Edition) -> SmolStr {
413+
let items_str = SmolStr::new_static("items");
414+
let Some(inner_ty) = inner_ty else {
415+
return items_str;
416+
};
417+
let Some(name) = name_of_type(inner_ty, db, edition) else {
418+
return items_str;
419+
};
420+
421+
if name.ends_with(['s', 'x', 'y']) {
422+
// Given a type called e.g. "Boss", "Fox" or "Story", don't try to
423+
// create a plural.
424+
items_str
425+
} else {
426+
SmolStr::new(format!("{name}s"))
427+
}
428+
}
429+
399430
fn trait_name(trait_: &hir::Trait, db: &RootDatabase, edition: Edition) -> Option<String> {
400431
let name = trait_.name(db).display(db, edition).to_string();
401432
if USELESS_TRAITS.contains(&name.as_str()) {
@@ -897,6 +928,58 @@ fn foo() { $0(bar())$0; }
897928
);
898929
}
899930

931+
#[test]
932+
fn vec_value() {
933+
check(
934+
r#"
935+
struct Vec<T> {};
936+
struct Seed;
937+
fn bar() -> Vec<Seed> {}
938+
fn foo() { $0(bar())$0; }
939+
"#,
940+
"seeds",
941+
);
942+
}
943+
944+
#[test]
945+
fn vec_value_ends_with_s() {
946+
check(
947+
r#"
948+
struct Vec<T> {};
949+
struct Boss;
950+
fn bar() -> Vec<Boss> {}
951+
fn foo() { $0(bar())$0; }
952+
"#,
953+
"items",
954+
);
955+
}
956+
957+
#[test]
958+
fn vecdeque_value() {
959+
check(
960+
r#"
961+
struct VecDeque<T> {};
962+
struct Seed;
963+
fn bar() -> VecDeque<Seed> {}
964+
fn foo() { $0(bar())$0; }
965+
"#,
966+
"seeds",
967+
);
968+
}
969+
970+
#[test]
971+
fn slice_value() {
972+
check(
973+
r#"
974+
struct Vec<T> {};
975+
struct Seed;
976+
fn bar() -> &[Seed] {}
977+
fn foo() { $0(bar())$0; }
978+
"#,
979+
"seeds",
980+
);
981+
}
982+
900983
#[test]
901984
fn ref_call() {
902985
check(

0 commit comments

Comments
 (0)