Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/ide-assists/src/utils/suggest_name.rs')
-rw-r--r--crates/ide-assists/src/utils/suggest_name.rs35
1 files changed, 29 insertions, 6 deletions
diff --git a/crates/ide-assists/src/utils/suggest_name.rs b/crates/ide-assists/src/utils/suggest_name.rs
index 05d38117d4..b4c6cbff2a 100644
--- a/crates/ide-assists/src/utils/suggest_name.rs
+++ b/crates/ide-assists/src/utils/suggest_name.rs
@@ -1,5 +1,7 @@
//! This module contains functions to suggest names for expressions, functions and other items
+use std::collections::HashSet;
+
use hir::Semantics;
use ide_db::RootDatabase;
use itertools::Itertools;
@@ -58,6 +60,14 @@ const USELESS_METHODS: &[&str] = &[
"into_future",
];
+/// Suggest a unique name for generic parameter.
+///
+/// `existing_params` is used to check if the name conflicts with existing
+/// generic parameters.
+///
+/// The function checks if the name conflicts with existing generic parameters.
+/// If so, it will try to resolve the conflict by adding a number suffix, e.g.
+/// `T`, `T0`, `T1`, ...
pub(crate) fn for_unique_generic_name(
name: &str,
existing_params: &ast::GenericParamList,
@@ -68,12 +78,9 @@ pub(crate) fn for_unique_generic_name(
ast::GenericParam::TypeParam(t) => t.name().unwrap().to_string(),
p => p.to_string(),
})
- .collect_vec();
+ .collect::<HashSet<_>>();
let mut name = name.to_string();
let base_len = name.len();
- // 4*len bytes for base, and 2 bytes for 2 digits
- name.reserve(4 * base_len + 2);
-
let mut count = 0;
while param_names.contains(&name) {
name.truncate(base_len);
@@ -84,12 +91,28 @@ pub(crate) fn for_unique_generic_name(
name.into()
}
-pub(crate) fn for_generic_parameter(ty: &ast::ImplTraitType) -> SmolStr {
+/// Suggest name of impl trait type
+///
+/// `existing_params` is used to check if the name conflicts with existing
+/// generic parameters.
+///
+/// # Current implementation
+///
+/// In current implementation, the function tries to get the name from the first
+/// character of the name for the first type bound.
+///
+/// If the name conflicts with existing generic parameters, it will try to
+/// resolve the conflict with `for_unique_generic_name`.
+pub(crate) fn for_impl_trait_as_generic(
+ ty: &ast::ImplTraitType,
+ existing_params: &ast::GenericParamList,
+) -> SmolStr {
let c = ty
.type_bound_list()
.and_then(|bounds| bounds.syntax().text().char_at(0.into()))
.unwrap_or('T');
- c.encode_utf8(&mut [0; 4]).into()
+
+ for_unique_generic_name(c.encode_utf8(&mut [0; 4]), existing_params)
}
/// Suggest name of variable for given expression