@@ -58,7 +58,48 @@ const USELESS_METHODS: &[&str] = &[
5858 "into_future" ,
5959] ;
6060
61- pub ( crate ) fn for_generic_parameter (
61+ /// Suggest a unique name for generic parameter.
62+ ///
63+ /// `existing_params` is used to check if the name conflicts with existing
64+ /// generic parameters.
65+ ///
66+ /// The function checks if the name conflicts with existing generic parameters.
67+ /// If so, it will try to resolve the conflict by adding a number suffix, e.g.
68+ /// `T`, `T0`, `T1`, ...
69+ pub ( crate ) fn for_unique_generic_name (
70+ name : & str ,
71+ existing_params : & ast:: GenericParamList ,
72+ ) -> SmolStr {
73+ let param_names = existing_params. generic_params ( ) . map ( |param| param. to_string ( ) ) . collect_vec ( ) ;
74+
75+ let mut name = name. to_string ( ) ;
76+ let base_len = name. len ( ) ;
77+ // 4*len bytes for base, and 2 bytes for 2 digits
78+ name. reserve ( 4 * base_len + 2 ) ;
79+
80+ let mut count = 0 ;
81+ while param_names. contains ( & name) {
82+ name. truncate ( base_len) ;
83+ name. push_str ( & count. to_string ( ) ) ;
84+ count += 1 ;
85+ }
86+
87+ name. into ( )
88+ }
89+
90+ /// Suggest name of impl trait type
91+ ///
92+ /// `existing_params` is used to check if the name conflicts with existing
93+ /// generic parameters.
94+ ///
95+ /// # Current implementation
96+ ///
97+ /// In current implementation, the function tries to get the name from the first
98+ /// character of the name for the first type bound.
99+ ///
100+ /// If the name conflicts with existing generic parameters, it will try to
101+ /// resolve the conflict with `for_unique_generic_name`.
102+ pub ( crate ) fn for_impl_trait_as_generic (
62103 ty : & ast:: ImplTraitType ,
63104 existing_params : & ast:: GenericParamList ,
64105) -> SmolStr {
@@ -67,34 +108,7 @@ pub(crate) fn for_generic_parameter(
67108 . and_then ( |bounds| bounds. syntax ( ) . text ( ) . char_at ( 0 . into ( ) ) )
68109 . unwrap_or ( 'T' ) ;
69110
70- // let existing_params = existing_params.generic_params();
71- let conflict = existing_params
72- . generic_params ( )
73- . filter ( |param| {
74- param. syntax ( ) . text_range ( ) . len ( ) == 1 . into ( )
75- && param. syntax ( ) . text ( ) . char_at ( 0 . into ( ) ) . unwrap ( ) == c
76- } )
77- . count ( )
78- > 0 ;
79-
80- let buffer = & mut [ 0 ; 4 ] ;
81- if conflict {
82- let mut name = String :: from ( c. encode_utf8 ( buffer) ) ;
83- name. reserve ( 6 ) ; // 4B for c, and 2B for 2 digits
84- let base_len = name. len ( ) ;
85- let mut count = 0 ;
86- loop {
87- name. truncate ( base_len) ;
88- name. push_str ( & count. to_string ( ) ) ;
89- if existing_params. generic_params ( ) . all ( |param| param. to_string ( ) != name) {
90- break ;
91- }
92- count += 1 ;
93- }
94- SmolStr :: from ( name)
95- } else {
96- c. encode_utf8 ( buffer) . into ( )
97- }
111+ for_unique_generic_name ( c. encode_utf8 ( & mut [ 0 ; 4 ] ) , existing_params)
98112}
99113
100114/// Suggest name of variable for given expression
0 commit comments