1
- use ide_db:: text_edit:: TextRange ;
2
1
use ide_db:: {
3
2
assists:: { AssistId , AssistKind } ,
4
3
defs:: Definition ,
5
4
search:: { FileReference , SearchScope , UsageSearchResult } ,
5
+ syntax_helpers:: suggest_name,
6
+ text_edit:: TextRange ,
6
7
} ;
7
8
use itertools:: Itertools ;
9
+ use syntax:: SmolStr ;
8
10
use syntax:: {
9
11
ast:: { self , make, AstNode , FieldExpr , HasName , IdentPat } ,
10
12
ted,
@@ -131,24 +133,31 @@ fn collect_data(ident_pat: IdentPat, ctx: &AssistContext<'_>) -> Option<TupleDat
131
133
. all ( )
132
134
} ) ;
133
135
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
+ } )
136
156
. collect :: < Vec < _ > > ( ) ;
137
157
138
158
Some ( TupleData { ident_pat, ref_type, field_names, usages } )
139
159
}
140
160
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
-
152
161
enum RefType {
153
162
ReadOnly ,
154
163
Mutable ,
@@ -1769,14 +1778,14 @@ struct S4 {
1769
1778
}
1770
1779
1771
1780
fn 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);
1773
1782
let v: i32 = *_0; // deref, no parens
1774
1783
let v: &i32 = _0; // no deref, no parens, remove `&`
1775
1784
f1(*_0); // deref, no parens
1776
1785
f2(_0); // `&*` -> cancel out -> no deref, no parens
1777
1786
// https://github.com/rust-lang/rust-analyzer/issues/1109#issuecomment-658868639
1778
1787
// 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
1780
1789
(*_0).do_stuff(); // deref, parens
1781
1790
let v: i32 = (*_2)?; // deref, parens
1782
1791
let v: i32 = _3[0]; // no deref, no parens
@@ -1815,8 +1824,8 @@ impl S {
1815
1824
}
1816
1825
1817
1826
fn main() {
1818
- let ($0_0 , _1) = &(S,2);
1819
- let s = _0 .f();
1827
+ let ($0s , _1) = &(S,2);
1828
+ let s = s .f();
1820
1829
}
1821
1830
"# ,
1822
1831
)
@@ -1845,8 +1854,8 @@ impl S {
1845
1854
}
1846
1855
1847
1856
fn main() {
1848
- let ($0_0 , _1) = &(S,2);
1849
- let s = (*_0 ).f();
1857
+ let ($0s , _1) = &(S,2);
1858
+ let s = (*s ).f();
1850
1859
}
1851
1860
"# ,
1852
1861
)
@@ -1882,8 +1891,8 @@ impl T for &S {
1882
1891
}
1883
1892
1884
1893
fn main() {
1885
- let ($0_0 , _1) = &(S,2);
1886
- let s = (*_0 ).f();
1894
+ let ($0s , _1) = &(S,2);
1895
+ let s = (*s ).f();
1887
1896
}
1888
1897
"# ,
1889
1898
)
@@ -1923,8 +1932,8 @@ impl T for &S {
1923
1932
}
1924
1933
1925
1934
fn main() {
1926
- let ($0_0 , _1) = &(S,2);
1927
- let s = (*_0 ).f();
1935
+ let ($0s , _1) = &(S,2);
1936
+ let s = (*s ).f();
1928
1937
}
1929
1938
"# ,
1930
1939
)
@@ -1951,8 +1960,8 @@ impl S {
1951
1960
fn do_stuff(&self) -> i32 { 42 }
1952
1961
}
1953
1962
fn 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();
1956
1965
}
1957
1966
"# ,
1958
1967
)
@@ -1973,7 +1982,7 @@ fn main() {
1973
1982
// `t.0` gets auto-refed -> no deref needed -> no parens
1974
1983
let v = t.0.do_stuff(); // no deref, no parens
1975
1984
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`
1977
1986
let v = t.1.do_stuff(); // deref, parens
1978
1987
}
1979
1988
"# ,
@@ -1984,13 +1993,13 @@ impl S {
1984
1993
fn do_stuff(&self) -> i32 { 42 }
1985
1994
}
1986
1995
fn 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
1989
1998
// `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
1994
2003
}
1995
2004
"# ,
1996
2005
)
0 commit comments