@@ -310,115 +310,27 @@ pub fn rewrite_macro_def(
310
310
311
311
let multi_branch_style = def. legacy || parsed_def. branches . len ( ) != 1 ;
312
312
313
- let mac_indent = if multi_branch_style {
314
- indent. block_indent ( context. config )
313
+ let arm_shape = if multi_branch_style {
314
+ shape
315
+ . block_indent ( context. config . tab_spaces ( ) )
316
+ . with_max_width ( context. config )
315
317
} else {
316
- indent
318
+ shape
317
319
} ;
318
320
319
- let mac_indent_str = mac_indent. to_string ( context. config ) ;
320
-
321
321
let branch_items = itemize_list (
322
322
context. codemap ,
323
323
parsed_def. branches . iter ( ) ,
324
324
"}" ,
325
325
";" ,
326
326
|branch| branch. span . lo ( ) ,
327
327
|branch| branch. span . hi ( ) ,
328
- |branch| {
329
- // Only attempt to format function-like macros.
330
- if branch. args_paren_kind != DelimToken :: Paren {
331
- // FIXME(#1539): implement for non-sugared macros.
332
- return None ;
333
- }
334
-
335
- let mut result = format_macro_args ( branch. args . clone ( ) ) ?;
336
-
337
- if multi_branch_style {
338
- result += " =>" ;
339
- }
340
-
341
- // The macro body is the most interesting part. It might end up as various
342
- // AST nodes, but also has special variables (e.g, `$foo`) which can't be
343
- // parsed as regular Rust code (and note that these can be escaped using
344
- // `$$`). We'll try and format like an AST node, but we'll substitute
345
- // variables for new names with the same length first.
346
-
347
- let old_body = context. snippet ( branch. body ) . trim ( ) ;
348
- let ( body_str, substs) = replace_names ( old_body) ;
349
-
350
- let mut config = context. config . clone ( ) ;
351
- config. set ( ) . hide_parse_errors ( true ) ;
352
-
353
- result += " {" ;
354
-
355
- let has_block_body = old_body. starts_with ( '{' ) ;
356
-
357
- let body_indent = if has_block_body {
358
- mac_indent
359
- } else {
360
- // We'll hack the indent below, take this into account when formatting,
361
- let body_indent = mac_indent. block_indent ( & config) ;
362
- let new_width = config. max_width ( ) - body_indent. width ( ) ;
363
- config. set ( ) . max_width ( new_width) ;
364
- body_indent
365
- } ;
366
-
367
- // First try to format as items, then as statements.
368
- let new_body = match :: format_snippet ( & body_str, & config) {
369
- Some ( new_body) => new_body,
370
- None => match :: format_code_block ( & body_str, & config) {
371
- Some ( new_body) => new_body,
372
- None => return None ,
373
- } ,
374
- } ;
375
-
376
- // Indent the body since it is in a block.
377
- let indent_str = body_indent. to_string ( & config) ;
378
- let mut new_body = new_body
379
- . trim_right ( )
380
- . lines ( )
381
- . fold ( String :: new ( ) , |mut s, l| {
382
- if !l. is_empty ( ) {
383
- s += & indent_str;
384
- }
385
- s + l + "\n "
386
- } ) ;
387
-
388
- // Undo our replacement of macro variables.
389
- // FIXME: this could be *much* more efficient.
390
- for ( old, new) in & substs {
391
- if old_body. find ( new) . is_some ( ) {
392
- debug ! (
393
- "rewrite_macro_def: bailing matching variable: `{}` in `{}`" ,
394
- new, ident
395
- ) ;
396
- return None ;
397
- }
398
- new_body = new_body. replace ( new, old) ;
399
- }
400
-
401
- if has_block_body {
402
- result += new_body. trim ( ) ;
403
- } else if !new_body. is_empty ( ) {
404
- result += "\n " ;
405
- result += & new_body;
406
- result += & mac_indent_str;
407
- }
408
-
409
- result += "}" ;
410
-
411
- Some ( result)
412
- } ,
328
+ |branch| branch. rewrite ( context, arm_shape, multi_branch_style) ,
413
329
context. codemap . span_after ( span, "{" ) ,
414
330
span. hi ( ) ,
415
331
false ,
416
332
) . collect :: < Vec < _ > > ( ) ;
417
333
418
- let arm_shape = shape
419
- . block_indent ( context. config . tab_spaces ( ) )
420
- . with_max_width ( context. config ) ;
421
-
422
334
let fmt = ListFormatting {
423
335
tactic : DefinitiveListTactic :: Vertical ,
424
336
separator : if def. legacy { ";" } else { "" } ,
@@ -432,7 +344,7 @@ pub fn rewrite_macro_def(
432
344
433
345
if multi_branch_style {
434
346
result += " {\n " ;
435
- result += & mac_indent_str ;
347
+ result += & arm_shape . indent . to_string ( context . config ) ;
436
348
}
437
349
438
350
result += write_list ( & branch_items, & fmt) ?. as_str ( ) ;
@@ -827,6 +739,94 @@ struct MacroBranch {
827
739
body : Span ,
828
740
}
829
741
742
+ impl MacroBranch {
743
+ fn rewrite ( & self , context : & RewriteContext , shape : Shape , multi_branch_style : bool ) -> Option < String > {
744
+ // Only attempt to format function-like macros.
745
+ if self . args_paren_kind != DelimToken :: Paren {
746
+ // FIXME(#1539): implement for non-sugared macros.
747
+ return None ;
748
+ }
749
+
750
+ let mut result = format_macro_args ( self . args . clone ( ) ) ?;
751
+
752
+ if multi_branch_style {
753
+ result += " =>" ;
754
+ }
755
+
756
+ // The macro body is the most interesting part. It might end up as various
757
+ // AST nodes, but also has special variables (e.g, `$foo`) which can't be
758
+ // parsed as regular Rust code (and note that these can be escaped using
759
+ // `$$`). We'll try and format like an AST node, but we'll substitute
760
+ // variables for new names with the same length first.
761
+
762
+ let old_body = context. snippet ( self . body ) . trim ( ) ;
763
+ let ( body_str, substs) = replace_names ( old_body) ;
764
+
765
+ let mut config = context. config . clone ( ) ;
766
+ config. set ( ) . hide_parse_errors ( true ) ;
767
+
768
+ result += " {" ;
769
+
770
+ let has_block_body = old_body. starts_with ( '{' ) ;
771
+
772
+ let body_indent = if has_block_body {
773
+ shape. indent
774
+ } else {
775
+ // We'll hack the indent below, take this into account when formatting,
776
+ let body_indent = shape. indent . block_indent ( & config) ;
777
+ let new_width = config. max_width ( ) - body_indent. width ( ) ;
778
+ config. set ( ) . max_width ( new_width) ;
779
+ body_indent
780
+ } ;
781
+
782
+ // First try to format as items, then as statements.
783
+ let new_body = match :: format_snippet ( & body_str, & config) {
784
+ Some ( new_body) => new_body,
785
+ None => match :: format_code_block ( & body_str, & config) {
786
+ Some ( new_body) => new_body,
787
+ None => return None ,
788
+ } ,
789
+ } ;
790
+
791
+ // Indent the body since it is in a block.
792
+ let indent_str = body_indent. to_string ( & config) ;
793
+ let mut new_body = new_body
794
+ . trim_right ( )
795
+ . lines ( )
796
+ . fold ( String :: new ( ) , |mut s, l| {
797
+ if !l. is_empty ( ) {
798
+ s += & indent_str;
799
+ }
800
+ s + l + "\n "
801
+ } ) ;
802
+
803
+ // Undo our replacement of macro variables.
804
+ // FIXME: this could be *much* more efficient.
805
+ for ( old, new) in & substs {
806
+ if old_body. find ( new) . is_some ( ) {
807
+ debug ! (
808
+ "rewrite_macro_def: bailing matching variable: `{}`" ,
809
+ new
810
+ ) ;
811
+ return None ;
812
+ }
813
+ new_body = new_body. replace ( new, old) ;
814
+ }
815
+
816
+ if has_block_body {
817
+ result += new_body. trim ( ) ;
818
+ } else if !new_body. is_empty ( ) {
819
+ result += "\n " ;
820
+ result += & new_body;
821
+ result += & shape. indent . to_string ( & config) ;
822
+ }
823
+
824
+ result += "}" ;
825
+
826
+ Some ( result)
827
+ }
828
+ }
829
+
830
830
#[ cfg( test) ]
831
831
mod test {
832
832
use super :: * ;
0 commit comments