@@ -446,58 +446,21 @@ impl<'a> FmtVisitor<'a> {
446
446
}
447
447
448
448
pub fn format_impl ( context : & RewriteContext , item : & ast:: Item , offset : Indent ) -> Option < String > {
449
- if let ast:: ItemKind :: Impl ( unsafety,
450
- polarity,
451
- ref generics,
452
- ref trait_ref,
453
- ref self_ty,
454
- ref items) = item. node {
449
+ if let ast:: ItemKind :: Impl ( _, _, ref generics, ref trait_ref, _, ref items) = item. node {
455
450
let mut result = String :: new ( ) ;
456
451
457
- result. push_str ( & * format_visibility ( & item. vis ) ) ;
458
- result. push_str ( format_unsafety ( unsafety) ) ;
459
- result. push_str ( "impl" ) ;
460
-
461
- let lo = context. codemap . span_after ( item. span , "impl" ) ;
462
- let hi = match * trait_ref {
463
- Some ( ref tr) => tr. path . span . lo ,
464
- None => self_ty. span . lo ,
465
- } ;
466
- let generics_str = try_opt ! ( rewrite_generics( context,
467
- generics,
468
- offset,
469
- context. config. max_width,
470
- offset + result. len( ) ,
471
- mk_sp( lo, hi) ) ) ;
472
- result. push_str ( & generics_str) ;
473
-
474
- // FIXME might need to linebreak in the impl header, here would be a
475
- // good place.
476
- result. push ( ' ' ) ;
477
- if polarity == ast:: ImplPolarity :: Negative {
478
- result. push_str ( "!" ) ;
479
- }
480
- if let Some ( ref trait_ref) = * trait_ref {
481
- let budget = try_opt ! ( context. config. max_width. checked_sub( result. len( ) ) ) ;
482
- let indent = offset + result. len ( ) ;
483
- result. push_str ( & * try_opt ! ( trait_ref. rewrite( context, budget, indent) ) ) ;
484
- result. push_str ( " for " ) ;
485
- }
452
+ // First try to format the ref and type without a split at the 'for'.
453
+ let mut ref_and_type = try_opt ! ( format_impl_ref_and_type( context, item, offset, false ) ) ;
486
454
487
- let mut used_space = result. len ( ) ;
488
- if generics. where_clause . predicates . is_empty ( ) {
489
- // If there is no where clause adapt budget for type formatting to take space and curly
490
- // brace into account.
491
- match context. config . item_brace_style {
492
- BraceStyle :: AlwaysNextLine => { }
493
- BraceStyle :: PreferSameLine => used_space += 2 ,
494
- BraceStyle :: SameLineWhere => used_space += 2 ,
455
+ // If there is a line break present in the first result format it again
456
+ // with a split at the 'for'. Skip this if there is no trait ref and
457
+ // therefore no 'for'.
458
+ if let Some ( _) = * trait_ref {
459
+ if ref_and_type. contains ( '\n' ) {
460
+ ref_and_type = try_opt ! ( format_impl_ref_and_type( context, item, offset, true ) ) ;
495
461
}
496
462
}
497
-
498
- let budget = try_opt ! ( context. config. max_width. checked_sub( used_space) ) ;
499
- let indent = offset + result. len ( ) ;
500
- result. push_str ( & * try_opt ! ( self_ty. rewrite( context, budget, indent) ) ) ;
463
+ result. push_str ( & ref_and_type) ;
501
464
502
465
let where_budget = try_opt ! ( context. config. max_width. checked_sub( last_line_width( & result) ) ) ;
503
466
let where_clause_str = try_opt ! ( rewrite_where_clause( context,
@@ -594,6 +557,76 @@ fn is_impl_single_line(context: &RewriteContext,
594
557
!contains_comment ( & snippet[ open_pos..] ) )
595
558
}
596
559
560
+ fn format_impl_ref_and_type ( context : & RewriteContext ,
561
+ item : & ast:: Item ,
562
+ offset : Indent ,
563
+ split_at_for : bool )
564
+ -> Option < String > {
565
+ if let ast:: ItemKind :: Impl ( unsafety, polarity, ref generics, ref trait_ref, ref self_ty, _) =
566
+ item. node {
567
+ let mut result = String :: new ( ) ;
568
+
569
+ result. push_str ( & * format_visibility ( & item. vis ) ) ;
570
+ result. push_str ( format_unsafety ( unsafety) ) ;
571
+ result. push_str ( "impl" ) ;
572
+
573
+ let lo = context. codemap . span_after ( item. span , "impl" ) ;
574
+ let hi = match * trait_ref {
575
+ Some ( ref tr) => tr. path . span . lo ,
576
+ None => self_ty. span . lo ,
577
+ } ;
578
+ let generics_str = try_opt ! ( rewrite_generics( context,
579
+ generics,
580
+ offset,
581
+ context. config. max_width,
582
+ offset + result. len( ) ,
583
+ mk_sp( lo, hi) ) ) ;
584
+ result. push_str ( & generics_str) ;
585
+
586
+ result. push ( ' ' ) ;
587
+ if polarity == ast:: ImplPolarity :: Negative {
588
+ result. push ( '!' ) ;
589
+ }
590
+ if let Some ( ref trait_ref) = * trait_ref {
591
+ let budget = try_opt ! ( context. config. max_width. checked_sub( result. len( ) ) ) ;
592
+ let indent = offset + result. len ( ) ;
593
+ result. push_str ( & * try_opt ! ( trait_ref. rewrite( context, budget, indent) ) ) ;
594
+
595
+ if split_at_for {
596
+ result. push ( '\n' ) ;
597
+
598
+ // Add indentation of one additional tab.
599
+ let width = context. block_indent . width ( ) + context. config . tab_spaces ;
600
+ let for_indent = Indent :: new ( 0 , width) ;
601
+ result. push_str ( & for_indent. to_string ( context. config ) ) ;
602
+
603
+ result. push_str ( "for " ) ;
604
+ } else {
605
+ result. push_str ( " for " ) ;
606
+ }
607
+ }
608
+
609
+ let mut used_space = last_line_width ( & result) ;
610
+ if generics. where_clause . predicates . is_empty ( ) {
611
+ // If there is no where clause adapt budget for type formatting to take space and curly
612
+ // brace into account.
613
+ match context. config . item_brace_style {
614
+ BraceStyle :: AlwaysNextLine => { }
615
+ BraceStyle :: PreferSameLine => used_space += 2 ,
616
+ BraceStyle :: SameLineWhere => used_space += 2 ,
617
+ }
618
+ }
619
+
620
+ let budget = try_opt ! ( context. config. max_width. checked_sub( used_space) ) ;
621
+ let indent = offset + result. len ( ) ;
622
+ result. push_str ( & * try_opt ! ( self_ty. rewrite( context, budget, indent) ) ) ;
623
+
624
+ Some ( result)
625
+ } else {
626
+ unreachable ! ( ) ;
627
+ }
628
+ }
629
+
597
630
pub fn format_struct ( context : & RewriteContext ,
598
631
item_name : & str ,
599
632
ident : ast:: Ident ,
0 commit comments