Skip to content

Commit

Permalink
Auto merge of rust-lang#17993 - ChayimFriedman2:convert-to-tuple-attr…
Browse files Browse the repository at this point in the history
…s, r=Veykril

Consider field attributes when converting from tuple to named struct and the opposite

Fixes rust-lang#17983.

I tried to use the `SourceChangeBuilder::make_mut()` API, but it duplicated the attribute...
  • Loading branch information
bors committed Aug 29, 2024
2 parents cd377d9 + b3fcd8e commit 34e7e79
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -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();

Expand Down Expand Up @@ -975,6 +980,22 @@ impl HasAssoc for Struct {
let Self::Assoc { value } = a;
}
}
"#,
);
}

#[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);
"#,
);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -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};
Expand Down Expand Up @@ -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();

Expand Down Expand Up @@ -904,6 +908,19 @@ where
T: Foo,
{ pub field1: T }
"#,
);
}

#[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 }
"#,
);
}
Expand Down

0 comments on commit 34e7e79

Please sign in to comment.