about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_named_struct_to_tuple_struct.rs31
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_struct_to_named_struct.rs29
2 files changed, 49 insertions, 11 deletions
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_named_struct_to_tuple_struct.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_named_struct_to_tuple_struct.rs
index 37055979276..8d4ff84084b 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_named_struct_to_tuple_struct.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_named_struct_to_tuple_struct.rs
@@ -2,8 +2,8 @@ use either::Either;
 use ide_db::{defs::Definition, search::FileReference};
 use itertools::Itertools;
 use syntax::{
-    ast::{self, AstNode, HasGenericParams, HasVisibility},
-    match_ast, SyntaxKind,
+    ast::{self, AstNode, HasAttrs, HasGenericParams, HasVisibility},
+    match_ast, ted, SyntaxKind,
 };
 
 use crate::{assist_context::SourceChangeBuilder, AssistContext, AssistId, AssistKind, Assists};
@@ -87,9 +87,14 @@ fn edit_struct_def(
 ) {
     // Note that we don't need to consider macro files in this function because this is
     // currently not triggered for struct definitions inside macro calls.
-    let tuple_fields = record_fields
-        .fields()
-        .filter_map(|f| Some(ast::make::tuple_field(f.visibility(), f.ty()?)));
+    let tuple_fields = record_fields.fields().filter_map(|f| {
+        let field = ast::make::tuple_field(f.visibility(), f.ty()?).clone_for_update();
+        ted::insert_all(
+            ted::Position::first_child_of(field.syntax()),
+            f.attrs().map(|attr| attr.syntax().clone_subtree().clone_for_update().into()).collect(),
+        );
+        Some(field)
+    });
     let tuple_fields = ast::make::tuple_field_list(tuple_fields);
     let record_fields_text_range = record_fields.syntax().text_range();
 
@@ -978,4 +983,20 @@ impl HasAssoc for Struct {
 "#,
         );
     }
+
+    #[test]
+    fn fields_with_attrs() {
+        check_assist(
+            convert_named_struct_to_tuple_struct,
+            r#"
+pub struct $0Foo {
+    #[my_custom_attr]
+    value: u32,
+}
+"#,
+            r#"
+pub struct Foo(#[my_custom_attr] u32);
+"#,
+        );
+    }
 }
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_struct_to_named_struct.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_struct_to_named_struct.rs
index c72bd411d64..f01b4ea0fd4 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_struct_to_named_struct.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_tuple_struct_to_named_struct.rs
@@ -1,8 +1,8 @@
 use either::Either;
 use ide_db::defs::{Definition, NameRefClass};
 use syntax::{
-    ast::{self, AstNode, HasGenericParams, HasVisibility},
-    match_ast, SyntaxKind, SyntaxNode,
+    ast::{self, AstNode, HasAttrs, HasGenericParams, HasVisibility},
+    match_ast, ted, SyntaxKind, SyntaxNode,
 };
 
 use crate::{assist_context::SourceChangeBuilder, AssistContext, AssistId, AssistKind, Assists};
@@ -83,10 +83,14 @@ fn edit_struct_def(
     tuple_fields: ast::TupleFieldList,
     names: Vec<ast::Name>,
 ) {
-    let record_fields = tuple_fields
-        .fields()
-        .zip(names)
-        .filter_map(|(f, name)| Some(ast::make::record_field(f.visibility(), name, f.ty()?)));
+    let record_fields = tuple_fields.fields().zip(names).filter_map(|(f, name)| {
+        let field = ast::make::record_field(f.visibility(), name, f.ty()?).clone_for_update();
+        ted::insert_all(
+            ted::Position::first_child_of(field.syntax()),
+            f.attrs().map(|attr| attr.syntax().clone_subtree().clone_for_update().into()).collect(),
+        );
+        Some(field)
+    });
     let record_fields = ast::make::record_field_list(record_fields);
     let tuple_fields_text_range = tuple_fields.syntax().text_range();
 
@@ -907,4 +911,17 @@ where
 "#,
         );
     }
+
+    #[test]
+    fn fields_with_attrs() {
+        check_assist(
+            convert_tuple_struct_to_named_struct,
+            r#"
+pub struct $0Foo(#[my_custom_attr] u32);
+"#,
+            r#"
+pub struct Foo { #[my_custom_attr] field1: u32 }
+"#,
+        );
+    }
 }