1- use ide_db:: { FxIndexSet , source_change :: SourceChangeBuilder } ;
1+ use ide_db:: { FxIndexSet , syntax_helpers :: suggest_name :: NameGenerator } ;
22use syntax:: {
3- NodeOrToken , T ,
3+ NodeOrToken , SmolStr , T ,
44 ast:: {
55 self , AstNode , HasGenericParams , HasName ,
66 make:: { self , tokens} ,
77 syntax_factory:: SyntaxFactory ,
88 } ,
9- syntax_editor:: { Position , SyntaxEditor } ,
9+ syntax_editor:: { Position , SyntaxAnnotation , SyntaxEditor } ,
1010} ;
1111
1212use crate :: { AssistContext , AssistId , Assists } ;
@@ -35,37 +35,48 @@ pub(crate) fn add_missing_lifetime(acc: &mut Assists, ctx: &AssistContext<'_>) -
3535 let ( refs_without_lifetime, refs_with_lifetime) : ( Vec < _ > , Vec < _ > ) =
3636 all_inner_refs. into_iter ( ) . partition ( |ref_type| ref_type. lifetime ( ) . is_none ( ) ) ;
3737
38- let adt_declared_lifetimes: FxIndexSet < String > = node
38+ let adt_declared_lifetimes: FxIndexSet < SmolStr > = node
3939 . generic_param_list ( )
4040 . map ( |gen_list| {
4141 gen_list
4242 . lifetime_params ( )
4343 . filter_map ( |lt| lt. lifetime ( ) )
44- . map ( |lt| lt. text ( ) . to_string ( ) )
44+ . map ( |lt| lt. text ( ) . into ( ) )
4545 . collect ( )
4646 } )
4747 . unwrap_or_default ( ) ;
4848
49- let adt_undeclared_lifetimes: FxIndexSet < String > = refs_with_lifetime
49+ let adt_undeclared_lifetimes: FxIndexSet < SmolStr > = refs_with_lifetime
5050 . iter ( )
5151 . filter_map ( |ref_type| ref_type. lifetime ( ) )
52- . map ( |lt| lt. text ( ) . to_string ( ) )
52+ . map ( |lt| lt. text ( ) . into ( ) )
5353 . filter ( |lt_text| !adt_declared_lifetimes. contains ( lt_text) )
5454 . collect ( ) ;
5555
5656 if refs_without_lifetime. is_empty ( ) && adt_undeclared_lifetimes. is_empty ( ) {
5757 return None ;
5858 }
5959
60- add_and_declare_lifetimes ( acc, ctx, & node, adt_undeclared_lifetimes, refs_without_lifetime)
60+ let all_existing_lifetimes: Vec < SmolStr > =
61+ adt_declared_lifetimes. iter ( ) . chain ( adt_undeclared_lifetimes. iter ( ) ) . cloned ( ) . collect ( ) ;
62+
63+ add_and_declare_lifetimes (
64+ acc,
65+ ctx,
66+ & node,
67+ adt_undeclared_lifetimes,
68+ refs_without_lifetime,
69+ all_existing_lifetimes,
70+ )
6171}
6272
6373fn add_and_declare_lifetimes (
6474 acc : & mut Assists ,
6575 ctx : & AssistContext < ' _ > ,
6676 node : & ast:: Adt ,
67- adt_undeclared_lifetimes : FxIndexSet < String > ,
77+ adt_undeclared_lifetimes : FxIndexSet < SmolStr > ,
6878 refs_without_lifetime : Vec < ast:: RefType > ,
79+ all_existing_lifetimes : Vec < SmolStr > ,
6980) -> Option < ( ) > {
7081 let has_refs_without_lifetime = !refs_without_lifetime. is_empty ( ) ;
7182 let has_undeclared_lifetimes = !adt_undeclared_lifetimes. is_empty ( ) ;
@@ -76,6 +87,11 @@ fn add_and_declare_lifetimes(
7687 _ => return None ,
7788 } ;
7889
90+ let mut name_gen =
91+ NameGenerator :: new_with_names ( all_existing_lifetimes. iter ( ) . map ( |s| s. as_str ( ) ) ) ;
92+ let new_lifetime_name =
93+ if has_refs_without_lifetime { name_gen. for_lifetime ( ) } else { SmolStr :: default ( ) } ;
94+
7995 acc. add (
8096 AssistId :: quick_fix ( "add_missing_lifetime" ) ,
8197 message,
@@ -98,7 +114,7 @@ fn add_and_declare_lifetimes(
98114
99115 if has_refs_without_lifetime {
100116 has_undeclared_lifetimes. then ( || lifetime_elements. extend ( comma_and_space. clone ( ) ) ) ;
101- let lifetime = make. lifetime ( "'l" ) ;
117+ let lifetime = make. lifetime ( & new_lifetime_name ) ;
102118 new_lifetime_to_annotate = Some ( lifetime. clone ( ) ) ;
103119 lifetime_elements. push ( lifetime. syntax ( ) . clone ( ) . into ( ) ) ;
104120 }
0 commit comments