@@ -275,12 +275,12 @@ impl Rewrite for Chain {
275
275
} ;
276
276
277
277
formatter. format_root ( & self . parent , context, shape) ?;
278
- if let result @ Some ( _ ) = formatter. pure_root ( ) {
279
- return result;
278
+ if let Some ( result ) = formatter. pure_root ( ) {
279
+ return wrap_str ( result, context . config . max_width ( ) , shape ) ;
280
280
}
281
281
282
282
// Decide how to layout the rest of the chain.
283
- let child_shape = formatter. child_shape ( context, shape) ;
283
+ let child_shape = formatter. child_shape ( context, shape) ? ;
284
284
285
285
formatter. format_children ( context, child_shape) ?;
286
286
formatter. format_last_child ( context, shape, child_shape) ?;
@@ -309,7 +309,7 @@ trait ChainFormatter {
309
309
context : & RewriteContext ,
310
310
shape : Shape ,
311
311
) -> Option < ( ) > ;
312
- fn child_shape ( & self , context : & RewriteContext , shape : Shape ) -> Shape ;
312
+ fn child_shape ( & self , context : & RewriteContext , shape : Shape ) -> Option < Shape > ;
313
313
fn format_children ( & mut self , context : & RewriteContext , child_shape : Shape ) -> Option < ( ) > ;
314
314
fn format_last_child (
315
315
& mut self ,
@@ -414,8 +414,10 @@ impl<'a> ChainFormatterShared<'a> {
414
414
415
415
let all_in_one_line =
416
416
self . rewrites . iter ( ) . all ( |s| !s. contains ( '\n' ) ) && one_line_budget > 0 ;
417
- let last_shape = if all_in_one_line || extendable {
417
+ let last_shape = if all_in_one_line {
418
418
shape. sub_width ( last. tries ) ?
419
+ } else if extendable {
420
+ child_shape. sub_width ( last. tries ) ?
419
421
} else {
420
422
child_shape. sub_width ( shape. rhs_overhead ( context. config ) + last. tries ) ?
421
423
} ;
@@ -481,7 +483,7 @@ impl<'a> ChainFormatterShared<'a> {
481
483
if * context. force_one_line_chain . borrow ( ) {
482
484
return None ;
483
485
}
484
- child_shape. indent . to_string_with_newline ( context. config )
486
+ child_shape. to_string_with_newline ( context. config )
485
487
} ;
486
488
487
489
let mut rewrite_iter = self . rewrites . iter ( ) ;
@@ -512,37 +514,6 @@ impl<'a> ChainFormatterBlock<'a> {
512
514
is_block_like : Vec :: with_capacity ( chain. children . len ( ) + 1 ) ,
513
515
}
514
516
}
515
-
516
- // States whether an expression's last line exclusively consists of closing
517
- // parens, braces, and brackets in its idiomatic formatting.
518
- fn is_block_expr ( context : & RewriteContext , expr : & ast:: Expr , repr : & str ) -> bool {
519
- match expr. node {
520
- ast:: ExprKind :: Mac ( ..)
521
- | ast:: ExprKind :: Call ( ..)
522
- | ast:: ExprKind :: MethodCall ( ..)
523
- | ast:: ExprKind :: Struct ( ..)
524
- | ast:: ExprKind :: While ( ..)
525
- | ast:: ExprKind :: WhileLet ( ..)
526
- | ast:: ExprKind :: If ( ..)
527
- | ast:: ExprKind :: IfLet ( ..)
528
- | ast:: ExprKind :: Block ( ..)
529
- | ast:: ExprKind :: Loop ( ..)
530
- | ast:: ExprKind :: ForLoop ( ..)
531
- | ast:: ExprKind :: Match ( ..) => repr. contains ( '\n' ) ,
532
- ast:: ExprKind :: Paren ( ref expr)
533
- | ast:: ExprKind :: Binary ( _, _, ref expr)
534
- | ast:: ExprKind :: Index ( _, ref expr)
535
- | ast:: ExprKind :: Unary ( _, ref expr)
536
- | ast:: ExprKind :: Closure ( _, _, _, _, ref expr, _)
537
- | ast:: ExprKind :: Try ( ref expr)
538
- | ast:: ExprKind :: Yield ( Some ( ref expr) ) => Self :: is_block_expr ( context, expr, repr) ,
539
- // This can only be a string lit
540
- ast:: ExprKind :: Lit ( _) => {
541
- repr. contains ( '\n' ) && trimmed_last_line_width ( repr) <= context. config . tab_spaces ( )
542
- }
543
- _ => false ,
544
- }
545
- }
546
517
}
547
518
548
519
impl < ' a > ChainFormatter for ChainFormatterBlock < ' a > {
@@ -554,7 +525,7 @@ impl<'a> ChainFormatter for ChainFormatterBlock<'a> {
554
525
) -> Option < ( ) > {
555
526
let mut root_rewrite: String = parent. rewrite ( context, shape) ?;
556
527
557
- let mut root_ends_with_block = Self :: is_block_expr ( context, & parent. expr , & root_rewrite) ;
528
+ let mut root_ends_with_block = is_block_expr ( context, & parent. expr , & root_rewrite) ;
558
529
let tab_width = context. config . tab_spaces ( ) . saturating_sub ( shape. offset ) ;
559
530
560
531
while root_rewrite. len ( ) <= tab_width && !root_rewrite. contains ( '\n' ) {
@@ -565,7 +536,7 @@ impl<'a> ChainFormatter for ChainFormatterBlock<'a> {
565
536
None => break ,
566
537
}
567
538
568
- root_ends_with_block = Self :: is_block_expr ( context, & item. expr , & root_rewrite) ;
539
+ root_ends_with_block = is_block_expr ( context, & item. expr , & root_rewrite) ;
569
540
570
541
self . shared . children = & self . shared . children [ ..self . shared . children . len ( ) - 1 ] ;
571
542
if self . shared . children . is_empty ( ) {
@@ -577,19 +548,21 @@ impl<'a> ChainFormatter for ChainFormatterBlock<'a> {
577
548
Some ( ( ) )
578
549
}
579
550
580
- fn child_shape ( & self , context : & RewriteContext , shape : Shape ) -> Shape {
581
- if self . is_block_like [ 0 ] {
582
- shape
583
- } else {
584
- shape. block_indent ( context. config . tab_spaces ( ) )
585
- } . with_max_width ( context. config )
551
+ fn child_shape ( & self , context : & RewriteContext , shape : Shape ) -> Option < Shape > {
552
+ Some (
553
+ if self . is_block_like [ 0 ] {
554
+ shape. block_indent ( 0 )
555
+ } else {
556
+ shape. block_indent ( context. config . tab_spaces ( ) )
557
+ } . with_max_width ( context. config ) ,
558
+ )
586
559
}
587
560
588
561
fn format_children ( & mut self , context : & RewriteContext , child_shape : Shape ) -> Option < ( ) > {
589
562
for item in self . shared . children [ 1 ..] . iter ( ) . rev ( ) {
590
563
let rewrite = item. rewrite_postfix ( context, child_shape) ?;
591
564
self . is_block_like
592
- . push ( Self :: is_block_expr ( context, & item. expr , & rewrite) ) ;
565
+ . push ( is_block_expr ( context, & item. expr , & rewrite) ) ;
593
566
self . shared . rewrites . push ( rewrite) ;
594
567
}
595
568
Some ( ( ) )
@@ -618,12 +591,15 @@ impl<'a> ChainFormatter for ChainFormatterBlock<'a> {
618
591
// Format a chain using visual indent.
619
592
struct ChainFormatterVisual < ' a > {
620
593
shared : ChainFormatterShared < ' a > ,
594
+ // The extra offset from the chain's shape to the position of the `.`
595
+ offset : usize ,
621
596
}
622
597
623
598
impl < ' a > ChainFormatterVisual < ' a > {
624
599
fn new ( chain : & ' a Chain ) -> ChainFormatterVisual < ' a > {
625
600
ChainFormatterVisual {
626
601
shared : ChainFormatterShared :: new ( chain) ,
602
+ offset : 0 ,
627
603
}
628
604
}
629
605
}
@@ -635,23 +611,31 @@ impl<'a> ChainFormatter for ChainFormatterVisual<'a> {
635
611
context : & RewriteContext ,
636
612
shape : Shape ,
637
613
) -> Option < ( ) > {
638
- // Determines if we can continue formatting a given expression on the same line.
639
- fn is_continuable ( expr : & ast:: Expr ) -> bool {
640
- match expr. node {
641
- ast:: ExprKind :: Path ( ..) => true ,
642
- _ => false ,
643
- }
644
- }
645
-
646
614
let parent_shape = shape. visual_indent ( 0 ) ;
647
615
let mut root_rewrite = parent. rewrite ( context, parent_shape) ?;
616
+ let multiline = root_rewrite. contains ( '\n' ) ;
617
+ self . offset = if multiline {
618
+ last_line_width ( & root_rewrite) . saturating_sub ( shape. used_width ( ) )
619
+ } else {
620
+ trimmed_last_line_width ( & root_rewrite)
621
+ } ;
648
622
649
- if !root_rewrite . contains ( '\n' ) && is_continuable ( & parent. expr ) {
623
+ if !multiline || is_block_expr ( context , & parent. expr , & root_rewrite ) {
650
624
let item = & self . shared . children [ self . shared . children . len ( ) - 1 ] ;
651
- let overhead = last_line_width ( & root_rewrite) ;
652
- let shape = parent_shape. offset_left ( overhead) ?;
653
- let rewrite = item. rewrite_postfix ( context, shape) ?;
654
- root_rewrite. push_str ( & rewrite) ;
625
+ let child_shape = parent_shape
626
+ . visual_indent ( self . offset )
627
+ . sub_width ( self . offset ) ?;
628
+ let rewrite = item. rewrite_postfix ( context, child_shape) ?;
629
+ match wrap_str ( rewrite, context. config . max_width ( ) , shape) {
630
+ Some ( rewrite) => root_rewrite. push_str ( & rewrite) ,
631
+ None => {
632
+ // We couldn't fit in at the visual indent, try the last
633
+ // indent.
634
+ let rewrite = item. rewrite_postfix ( context, parent_shape) ?;
635
+ root_rewrite. push_str ( & rewrite) ;
636
+ self . offset = 0 ;
637
+ }
638
+ }
655
639
656
640
self . shared . children = & self . shared . children [ ..self . shared . children . len ( ) - 1 ] ;
657
641
}
@@ -660,8 +644,11 @@ impl<'a> ChainFormatter for ChainFormatterVisual<'a> {
660
644
Some ( ( ) )
661
645
}
662
646
663
- fn child_shape ( & self , context : & RewriteContext , shape : Shape ) -> Shape {
664
- shape. visual_indent ( 0 ) . with_max_width ( context. config )
647
+ fn child_shape ( & self , context : & RewriteContext , shape : Shape ) -> Option < Shape > {
648
+ shape
649
+ . with_max_width ( context. config )
650
+ . offset_left ( self . offset )
651
+ . map ( |s| s. visual_indent ( 0 ) )
665
652
}
666
653
667
654
fn format_children ( & mut self , context : & RewriteContext , child_shape : Shape ) -> Option < ( ) > {
@@ -691,3 +678,34 @@ impl<'a> ChainFormatter for ChainFormatterVisual<'a> {
691
678
self . shared . pure_root ( )
692
679
}
693
680
}
681
+
682
+ // States whether an expression's last line exclusively consists of closing
683
+ // parens, braces, and brackets in its idiomatic formatting.
684
+ fn is_block_expr ( context : & RewriteContext , expr : & ast:: Expr , repr : & str ) -> bool {
685
+ match expr. node {
686
+ ast:: ExprKind :: Mac ( ..)
687
+ | ast:: ExprKind :: Call ( ..)
688
+ | ast:: ExprKind :: MethodCall ( ..)
689
+ | ast:: ExprKind :: Struct ( ..)
690
+ | ast:: ExprKind :: While ( ..)
691
+ | ast:: ExprKind :: WhileLet ( ..)
692
+ | ast:: ExprKind :: If ( ..)
693
+ | ast:: ExprKind :: IfLet ( ..)
694
+ | ast:: ExprKind :: Block ( ..)
695
+ | ast:: ExprKind :: Loop ( ..)
696
+ | ast:: ExprKind :: ForLoop ( ..)
697
+ | ast:: ExprKind :: Match ( ..) => repr. contains ( '\n' ) ,
698
+ ast:: ExprKind :: Paren ( ref expr)
699
+ | ast:: ExprKind :: Binary ( _, _, ref expr)
700
+ | ast:: ExprKind :: Index ( _, ref expr)
701
+ | ast:: ExprKind :: Unary ( _, ref expr)
702
+ | ast:: ExprKind :: Closure ( _, _, _, _, ref expr, _)
703
+ | ast:: ExprKind :: Try ( ref expr)
704
+ | ast:: ExprKind :: Yield ( Some ( ref expr) ) => is_block_expr ( context, expr, repr) ,
705
+ // This can only be a string lit
706
+ ast:: ExprKind :: Lit ( _) => {
707
+ repr. contains ( '\n' ) && trimmed_last_line_width ( repr) <= context. config . tab_spaces ( )
708
+ }
709
+ _ => false ,
710
+ }
711
+ }
0 commit comments