1- use std:: iter;
2-
31use either:: Either ;
42use hir:: { Adt , FileRange , HasSource , HirDisplay , InFile , Struct , Union , db:: ExpandDatabase } ;
53use ide_db:: text_edit:: TextEdit ;
@@ -194,17 +192,20 @@ fn add_field_to_struct_fix(
194192 Some ( make:: visibility_pub_crate ( ) )
195193 } ;
196194 // FIXME: Allow for choosing a visibility modifier see https://github.com/rust-lang/rust-analyzer/issues/11563
197- let indent = IndentLevel :: from_node ( struct_syntax. value ) + 1 ;
195+ let indent = IndentLevel :: from_node ( struct_syntax. value ) ;
198196
199- let field = make :: record_field ( visibility , field_name , suggested_type ) . indent ( indent ) ;
200- let record_field_list = make:: record_field_list ( iter :: once ( field ) ) ;
197+ let field =
198+ make:: record_field ( visibility , field_name , suggested_type ) . indent ( indent + 1 ) ;
201199 // A Unit Struct with no `;` is invalid syntax. We should not suggest this fix.
202200 let semi_colon =
203201 algo:: skip_trivia_token ( struct_syntax. value . last_token ( ) ?, Direction :: Prev ) ?;
204202 if semi_colon. kind ( ) != SyntaxKind :: SEMICOLON {
205203 return None ;
206204 }
207- src_change_builder. replace ( semi_colon. text_range ( ) , record_field_list. to_string ( ) ) ;
205+ src_change_builder. replace (
206+ semi_colon. text_range ( ) ,
207+ format ! ( " {{\n {}{field},\n {indent}}}" , indent + 1 ) ,
208+ ) ;
208209
209210 Some ( Assist {
210211 id : AssistId :: quick_fix ( "convert-unit-struct-to-record-struct" ) ,
@@ -230,7 +231,7 @@ fn record_field_layout(
230231 field_list : ast:: RecordFieldList ,
231232 struct_syntax : & SyntaxNode ,
232233) -> Option < ( TextSize , String ) > {
233- let ( offset, needs_comma, trailing_new_line , indent) = match field_list. fields ( ) . last ( ) {
234+ let ( offset, needs_comma, indent) = match field_list. fields ( ) . last ( ) {
234235 Some ( record_field) => {
235236 let syntax = algo:: skip_trivia_token ( field_list. r_curly_token ( ) ?, Direction :: Prev ) ?;
236237
@@ -239,19 +240,22 @@ fn record_field_layout(
239240 (
240241 last_field_syntax. text_range ( ) . end ( ) ,
241242 syntax. kind ( ) != SyntaxKind :: COMMA ,
242- false ,
243243 last_field_indent,
244244 )
245245 }
246246 // Empty Struct. Add a field right before the closing brace
247247 None => {
248248 let indent = IndentLevel :: from_node ( struct_syntax) + 1 ;
249- let offset = field_list. r_curly_token ( ) ?. text_range ( ) . start ( ) ;
250- ( offset, false , true , indent)
249+ let offset = field_list. l_curly_token ( ) ?. text_range ( ) . end ( ) ;
250+ ( offset, false , indent)
251251 }
252252 } ;
253- let comma = if needs_comma { ",\n " } else { "" } ;
254- let trailing_new_line = if trailing_new_line { "\n " } else { "" } ;
253+ let trailing_new_line = if !field_list. syntax ( ) . text ( ) . contains_char ( '\n' ) {
254+ format ! ( "\n {}" , field_list. indent_level( ) )
255+ } else {
256+ String :: new ( )
257+ } ;
258+ let comma = if needs_comma { ",\n " } else { "\n " } ;
255259 let record_field = make:: record_field ( visibility, name, suggested_type) ;
256260
257261 Some ( ( offset, format ! ( "{comma}{indent}{record_field}{trailing_new_line}" ) ) )
@@ -377,34 +381,43 @@ fn foo() {
377381 fn unresolved_field_fix_on_unit ( ) {
378382 check_fix (
379383 r#"
384+ mod indent {
380385 struct Foo;
381386
382387 fn foo() {
383388 Foo.bar$0;
384389 }
390+ }
385391 "# ,
386392 r#"
387- struct Foo{ bar: () }
393+ mod indent {
394+ struct Foo {
395+ bar: (),
396+ }
388397
389398 fn foo() {
390399 Foo.bar;
391400 }
401+ }
392402 "# ,
393403 ) ;
394404 }
395405 #[ test]
396406 fn unresolved_field_fix_on_empty ( ) {
397407 check_fix (
398408 r#"
409+ mod indent {
399410 struct Foo{
400411 }
401412
402413 fn foo() {
403414 let foo = Foo{};
404415 foo.bar$0;
405416 }
417+ }
406418 "# ,
407419 r#"
420+ mod indent {
408421 struct Foo{
409422 bar: ()
410423 }
@@ -413,6 +426,32 @@ fn foo() {
413426 let foo = Foo{};
414427 foo.bar;
415428 }
429+ }
430+ "# ,
431+ ) ;
432+
433+ check_fix (
434+ r#"
435+ mod indent {
436+ struct Foo {}
437+
438+ fn foo() {
439+ let foo = Foo{};
440+ foo.bar$0;
441+ }
442+ }
443+ "# ,
444+ r#"
445+ mod indent {
446+ struct Foo {
447+ bar: ()
448+ }
449+
450+ fn foo() {
451+ let foo = Foo{};
452+ foo.bar;
453+ }
454+ }
416455 "# ,
417456 ) ;
418457 }
0 commit comments