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