@@ -154,14 +154,7 @@ fn edit_struct_references(
154154 ast:: TupleStructPat ( tuple_struct_pat) => {
155155 Some ( make. record_pat_with_fields(
156156 tuple_struct_pat. path( ) ?,
157- ast:: make:: record_pat_field_list( tuple_struct_pat. fields( ) . zip( names) . map(
158- |( pat, name) | {
159- ast:: make:: record_pat_field(
160- ast:: make:: name_ref( & name. to_string( ) ) ,
161- pat,
162- )
163- } ,
164- ) , None ) ,
157+ generate_record_pat_list( & tuple_struct_pat, names) ,
165158 ) . syntax( ) . clone( ) )
166159 } ,
167160 // for tuple struct creations like Foo(42)
@@ -284,6 +277,24 @@ fn generate_names(fields: impl Iterator<Item = ast::TupleField>) -> Vec<ast::Nam
284277 . collect ( )
285278}
286279
280+ fn generate_record_pat_list (
281+ pat : & ast:: TupleStructPat ,
282+ names : & [ ast:: Name ] ,
283+ ) -> ast:: RecordPatFieldList {
284+ let pure_fields = pat. fields ( ) . filter ( |p| !matches ! ( p, ast:: Pat :: RestPat ( _) ) ) ;
285+ let rest_len = names. len ( ) . saturating_sub ( pure_fields. clone ( ) . count ( ) ) ;
286+ let rest_pat = pat. fields ( ) . find_map ( |p| ast:: RestPat :: cast ( p. syntax ( ) . clone ( ) ) ) ;
287+ let rest_idx =
288+ pat. fields ( ) . position ( |p| ast:: RestPat :: can_cast ( p. syntax ( ) . kind ( ) ) ) . unwrap_or ( names. len ( ) ) ;
289+ let before_rest = pat. fields ( ) . zip ( names) . take ( rest_idx) ;
290+ let after_rest = pure_fields. zip ( names. iter ( ) . skip ( rest_len) ) . skip ( rest_idx) ;
291+
292+ let fields = before_rest
293+ . chain ( after_rest)
294+ . map ( |( pat, name) | ast:: make:: record_pat_field ( ast:: make:: name_ref ( & name. text ( ) ) , pat) ) ;
295+ ast:: make:: record_pat_field_list ( fields, rest_pat)
296+ }
297+
287298#[ cfg( test) ]
288299mod tests {
289300 use crate :: tests:: { check_assist, check_assist_not_applicable} ;
@@ -358,6 +369,43 @@ impl A {
358369 ) ;
359370 }
360371
372+ #[ test]
373+ fn convert_struct_and_rest_pat ( ) {
374+ check_assist (
375+ convert_tuple_struct_to_named_struct,
376+ r#"
377+ struct Inner;
378+ struct A$0(Inner);
379+ fn foo(A(..): A) {}
380+ "# ,
381+ r#"
382+ struct Inner;
383+ struct A { field1: Inner }
384+ fn foo(A { .. }: A) {}
385+ "# ,
386+ ) ;
387+
388+ check_assist (
389+ convert_tuple_struct_to_named_struct,
390+ r#"
391+ struct A;
392+ struct B;
393+ struct C;
394+ struct D;
395+ struct X$0(A, B, C, D);
396+ fn foo(X(a, .., d): X) {}
397+ "# ,
398+ r#"
399+ struct A;
400+ struct B;
401+ struct C;
402+ struct D;
403+ struct X { field1: A, field2: B, field3: C, field4: D }
404+ fn foo(X { field1: a, field4: d, .. }: X) {}
405+ "# ,
406+ ) ;
407+ }
408+
361409 #[ test]
362410 fn convert_simple_struct_cursor_on_struct_keyword ( ) {
363411 check_assist (
0 commit comments