1- use ide_db:: text_edit:: TextRange ;
21use ide_db:: {
32 assists:: { AssistId , AssistKind } ,
43 defs:: Definition ,
54 search:: { FileReference , SearchScope , UsageSearchResult } ,
5+ syntax_helpers:: suggest_name,
6+ text_edit:: TextRange ,
67} ;
78use itertools:: Itertools ;
9+ use syntax:: SmolStr ;
810use syntax:: {
911 ast:: { self , make, AstNode , FieldExpr , HasName , IdentPat } ,
1012 ted,
@@ -131,24 +133,31 @@ fn collect_data(ident_pat: IdentPat, ctx: &AssistContext<'_>) -> Option<TupleDat
131133 . all ( )
132134 } ) ;
133135
134- let field_names = ( 0 ..field_types. len ( ) )
135- . map ( |i| generate_name ( ctx, i, & name, & ident_pat, & usages) )
136+ let mut name_generator = {
137+ let mut names = vec ! [ ] ;
138+ ctx. sema . scope ( ident_pat. syntax ( ) ) ?. process_all_names ( & mut |name, scope| {
139+ if let hir:: ScopeDef :: Local ( _) = scope {
140+ names. push ( name. as_str ( ) . into ( ) )
141+ }
142+ } ) ;
143+ suggest_name:: NameGenerator :: new_with_names ( names. iter ( ) . map ( |s : & SmolStr | s. as_str ( ) ) )
144+ } ;
145+
146+ let field_names = field_types
147+ . into_iter ( )
148+ . enumerate ( )
149+ . map ( |( id, ty) | {
150+ match name_generator. for_type ( & ty, ctx. db ( ) , ctx. edition ( ) ) {
151+ Some ( name) => name,
152+ None => name_generator. suggest_name ( & format ! ( "_{}" , id) ) ,
153+ }
154+ . to_string ( )
155+ } )
136156 . collect :: < Vec < _ > > ( ) ;
137157
138158 Some ( TupleData { ident_pat, ref_type, field_names, usages } )
139159}
140160
141- fn generate_name (
142- _ctx : & AssistContext < ' _ > ,
143- index : usize ,
144- _tuple_name : & str ,
145- _ident_pat : & IdentPat ,
146- _usages : & Option < UsageSearchResult > ,
147- ) -> String {
148- // FIXME: detect if name already used
149- format ! ( "_{index}" )
150- }
151-
152161enum RefType {
153162 ReadOnly ,
154163 Mutable ,
@@ -1769,14 +1778,14 @@ struct S4 {
17691778}
17701779
17711780fn foo() -> Option<()> {
1772- let ($0_0, _1, _2, _3, _4 , _5) = &(0, (1,"1"), Some(2), [3;3], S4 { value: 4 }, &5);
1781+ let ($0_0, _1, _2, _3, s4 , _5) = &(0, (1,"1"), Some(2), [3;3], S4 { value: 4 }, &5);
17731782 let v: i32 = *_0; // deref, no parens
17741783 let v: &i32 = _0; // no deref, no parens, remove `&`
17751784 f1(*_0); // deref, no parens
17761785 f2(_0); // `&*` -> cancel out -> no deref, no parens
17771786 // https://github.com/rust-lang/rust-analyzer/issues/1109#issuecomment-658868639
17781787 // let v: i32 = t.1.0; // no deref, no parens
1779- let v: i32 = _4 .value; // no deref, no parens
1788+ let v: i32 = s4 .value; // no deref, no parens
17801789 (*_0).do_stuff(); // deref, parens
17811790 let v: i32 = (*_2)?; // deref, parens
17821791 let v: i32 = _3[0]; // no deref, no parens
@@ -1815,8 +1824,8 @@ impl S {
18151824}
18161825
18171826fn main() {
1818- let ($0_0 , _1) = &(S,2);
1819- let s = _0 .f();
1827+ let ($0s , _1) = &(S,2);
1828+ let s = s .f();
18201829}
18211830 "# ,
18221831 )
@@ -1845,8 +1854,8 @@ impl S {
18451854}
18461855
18471856fn main() {
1848- let ($0_0 , _1) = &(S,2);
1849- let s = (*_0 ).f();
1857+ let ($0s , _1) = &(S,2);
1858+ let s = (*s ).f();
18501859}
18511860 "# ,
18521861 )
@@ -1882,8 +1891,8 @@ impl T for &S {
18821891}
18831892
18841893fn main() {
1885- let ($0_0 , _1) = &(S,2);
1886- let s = (*_0 ).f();
1894+ let ($0s , _1) = &(S,2);
1895+ let s = (*s ).f();
18871896}
18881897 "# ,
18891898 )
@@ -1923,8 +1932,8 @@ impl T for &S {
19231932}
19241933
19251934fn main() {
1926- let ($0_0 , _1) = &(S,2);
1927- let s = (*_0 ).f();
1935+ let ($0s , _1) = &(S,2);
1936+ let s = (*s ).f();
19281937}
19291938 "# ,
19301939 )
@@ -1951,8 +1960,8 @@ impl S {
19511960 fn do_stuff(&self) -> i32 { 42 }
19521961}
19531962fn main() {
1954- let ($0_0, _1 ) = &(S,&S);
1955- let v = _0 .do_stuff();
1963+ let ($0s, s1 ) = &(S,&S);
1964+ let v = s .do_stuff();
19561965}
19571966 "# ,
19581967 )
@@ -1973,7 +1982,7 @@ fn main() {
19731982 // `t.0` gets auto-refed -> no deref needed -> no parens
19741983 let v = t.0.do_stuff(); // no deref, no parens
19751984 let v = &t.0.do_stuff(); // `&` is for result -> no deref, no parens
1976- // deref: `_1 ` is `&&S`, but method called is on `&S` -> there might be a method accepting `&&S`
1985+ // deref: `s1 ` is `&&S`, but method called is on `&S` -> there might be a method accepting `&&S`
19771986 let v = t.1.do_stuff(); // deref, parens
19781987}
19791988 "# ,
@@ -1984,13 +1993,13 @@ impl S {
19841993 fn do_stuff(&self) -> i32 { 42 }
19851994}
19861995fn main() {
1987- let ($0_0, _1 ) = &(S,&S);
1988- let v = _0 .do_stuff(); // no deref, remove parens
1996+ let ($0s, s1 ) = &(S,&S);
1997+ let v = s .do_stuff(); // no deref, remove parens
19891998 // `t.0` gets auto-refed -> no deref needed -> no parens
1990- let v = _0 .do_stuff(); // no deref, no parens
1991- let v = &_0 .do_stuff(); // `&` is for result -> no deref, no parens
1992- // deref: `_1 ` is `&&S`, but method called is on `&S` -> there might be a method accepting `&&S`
1993- let v = (*_1 ).do_stuff(); // deref, parens
1999+ let v = s .do_stuff(); // no deref, no parens
2000+ let v = &s .do_stuff(); // `&` is for result -> no deref, no parens
2001+ // deref: `s1 ` is `&&S`, but method called is on `&S` -> there might be a method accepting `&&S`
2002+ let v = (*s1 ).do_stuff(); // deref, parens
19942003}
19952004 "# ,
19962005 )
0 commit comments