@@ -730,7 +730,7 @@ struct ControlFlow<'a> {
730
730
block : & ' a ast:: Block ,
731
731
else_block : Option < & ' a ast:: Expr > ,
732
732
label : Option < ast:: Label > ,
733
- pat : Option < & ' a ast:: Pat > ,
733
+ pats : Option < Vec < & ' a ast:: Pat > > ,
734
734
keyword : & ' a str ,
735
735
matcher : & ' a str ,
736
736
connector : & ' a str ,
@@ -754,7 +754,7 @@ fn to_control_flow(expr: &ast::Expr, expr_type: ExprType) -> Option<ControlFlow>
754
754
ast:: ExprKind :: IfLet ( ref pat, ref cond, ref if_block, ref else_block) => {
755
755
Some ( ControlFlow :: new_if (
756
756
cond,
757
- Some ( pat) ,
757
+ Some ( ptr_vec_to_ref_vec ( pat) ) ,
758
758
if_block,
759
759
else_block. as_ref ( ) . map ( |e| & * * e) ,
760
760
expr_type == ExprType :: SubExpression ,
@@ -772,7 +772,7 @@ fn to_control_flow(expr: &ast::Expr, expr_type: ExprType) -> Option<ControlFlow>
772
772
Some ( ControlFlow :: new_while ( None , cond, block, label, expr. span ) )
773
773
}
774
774
ast:: ExprKind :: WhileLet ( ref pat, ref cond, ref block, label) => Some (
775
- ControlFlow :: new_while ( Some ( pat) , cond, block, label, expr. span ) ,
775
+ ControlFlow :: new_while ( Some ( ptr_vec_to_ref_vec ( pat) ) , cond, block, label, expr. span ) ,
776
776
) ,
777
777
_ => None ,
778
778
}
@@ -781,24 +781,25 @@ fn to_control_flow(expr: &ast::Expr, expr_type: ExprType) -> Option<ControlFlow>
781
781
impl < ' a > ControlFlow < ' a > {
782
782
fn new_if (
783
783
cond : & ' a ast:: Expr ,
784
- pat : Option < & ' a ast:: Pat > ,
784
+ pats : Option < Vec < & ' a ast:: Pat > > ,
785
785
block : & ' a ast:: Block ,
786
786
else_block : Option < & ' a ast:: Expr > ,
787
787
allow_single_line : bool ,
788
788
nested_if : bool ,
789
789
span : Span ,
790
790
) -> ControlFlow < ' a > {
791
+ let matcher = match pats {
792
+ Some ( ..) => "let" ,
793
+ None => "" ,
794
+ } ;
791
795
ControlFlow {
792
796
cond : Some ( cond) ,
793
797
block,
794
798
else_block,
795
799
label : None ,
796
- pat ,
800
+ pats ,
797
801
keyword : "if" ,
798
- matcher : match pat {
799
- Some ( ..) => "let" ,
800
- None => "" ,
801
- } ,
802
+ matcher,
802
803
connector : " =" ,
803
804
allow_single_line,
804
805
nested_if,
@@ -812,7 +813,7 @@ impl<'a> ControlFlow<'a> {
812
813
block,
813
814
else_block : None ,
814
815
label,
815
- pat : None ,
816
+ pats : None ,
816
817
keyword : "loop" ,
817
818
matcher : "" ,
818
819
connector : "" ,
@@ -823,23 +824,24 @@ impl<'a> ControlFlow<'a> {
823
824
}
824
825
825
826
fn new_while (
826
- pat : Option < & ' a ast:: Pat > ,
827
+ pats : Option < Vec < & ' a ast:: Pat > > ,
827
828
cond : & ' a ast:: Expr ,
828
829
block : & ' a ast:: Block ,
829
830
label : Option < ast:: Label > ,
830
831
span : Span ,
831
832
) -> ControlFlow < ' a > {
833
+ let matcher = match pats {
834
+ Some ( ..) => "let" ,
835
+ None => "" ,
836
+ } ;
832
837
ControlFlow {
833
838
cond : Some ( cond) ,
834
839
block,
835
840
else_block : None ,
836
841
label,
837
- pat ,
842
+ pats ,
838
843
keyword : "while" ,
839
- matcher : match pat {
840
- Some ( ..) => "let" ,
841
- None => "" ,
842
- } ,
844
+ matcher,
843
845
connector : " =" ,
844
846
allow_single_line : false ,
845
847
nested_if : false ,
@@ -859,7 +861,7 @@ impl<'a> ControlFlow<'a> {
859
861
block,
860
862
else_block : None ,
861
863
label,
862
- pat : Some ( pat) ,
864
+ pats : Some ( vec ! [ pat] ) ,
863
865
keyword : "for" ,
864
866
matcher : "" ,
865
867
connector : " in" ,
@@ -914,6 +916,46 @@ impl<'a> ControlFlow<'a> {
914
916
}
915
917
916
918
impl < ' a > ControlFlow < ' a > {
919
+ fn rewrite_pat_expr (
920
+ & self ,
921
+ context : & RewriteContext ,
922
+ expr : & ast:: Expr ,
923
+ shape : Shape ,
924
+ offset : usize ,
925
+ ) -> Option < String > {
926
+ debug ! ( "rewrite_pat_expr {:?} {:?} {:?}" , shape, self . pats, expr) ;
927
+
928
+ let cond_shape = shape. offset_left ( offset) ?;
929
+ if let Some ( ref pat) = self . pats {
930
+ let matcher = if self . matcher . is_empty ( ) {
931
+ self . matcher . to_owned ( )
932
+ } else {
933
+ format ! ( "{} " , self . matcher)
934
+ } ;
935
+ let pat_shape = cond_shape
936
+ . offset_left ( matcher. len ( ) ) ?
937
+ . sub_width ( self . connector . len ( ) ) ?;
938
+ let pat_string = rewrite_multiple_patterns ( context, pat, pat_shape) ?;
939
+ let result = format ! ( "{}{}{}" , matcher, pat_string, self . connector) ;
940
+ return rewrite_assign_rhs ( context, result, expr, cond_shape) ;
941
+ }
942
+
943
+ let expr_rw = expr. rewrite ( context, cond_shape) ;
944
+ // The expression may (partially) fit on the current line.
945
+ // We do not allow splitting between `if` and condition.
946
+ if self . keyword == "if" || expr_rw. is_some ( ) {
947
+ return expr_rw;
948
+ }
949
+
950
+ // The expression won't fit on the current line, jump to next.
951
+ let nested_shape = shape
952
+ . block_indent ( context. config . tab_spaces ( ) )
953
+ . with_max_width ( context. config ) ;
954
+ let nested_indent_str = nested_shape. indent . to_string_with_newline ( context. config ) ;
955
+ expr. rewrite ( context, nested_shape)
956
+ . map ( |expr_rw| format ! ( "{}{}" , nested_indent_str, expr_rw) )
957
+ }
958
+
917
959
fn rewrite_cond (
918
960
& self ,
919
961
context : & RewriteContext ,
@@ -922,11 +964,7 @@ impl<'a> ControlFlow<'a> {
922
964
) -> Option < ( String , usize ) > {
923
965
// Do not take the rhs overhead from the upper expressions into account
924
966
// when rewriting pattern.
925
- let new_width = context
926
- . config
927
- . max_width ( )
928
- . checked_sub ( shape. used_width ( ) )
929
- . unwrap_or ( 0 ) ;
967
+ let new_width = context. budget ( shape. used_width ( ) ) ;
930
968
let fresh_shape = Shape {
931
969
width : new_width,
932
970
..shape
@@ -944,16 +982,7 @@ impl<'a> ControlFlow<'a> {
944
982
let offset = self . keyword . len ( ) + label_string. len ( ) + 1 ;
945
983
946
984
let pat_expr_string = match self . cond {
947
- Some ( cond) => rewrite_pat_expr (
948
- context,
949
- self . pat ,
950
- cond,
951
- self . matcher ,
952
- self . connector ,
953
- self . keyword ,
954
- constr_shape,
955
- offset,
956
- ) ?,
985
+ Some ( cond) => self . rewrite_pat_expr ( context, cond, constr_shape, offset) ?,
957
986
None => String :: new ( ) ,
958
987
} ;
959
988
@@ -1007,9 +1036,9 @@ impl<'a> ControlFlow<'a> {
1007
1036
context
1008
1037
. snippet_provider
1009
1038
. span_after ( mk_sp ( lo, self . span . hi ( ) ) , self . keyword . trim ( ) ) ,
1010
- self . pat . map_or ( cond_span. lo ( ) , |p| {
1039
+ self . pats . as_ref ( ) . map_or ( cond_span. lo ( ) , |p| {
1011
1040
if self . matcher . is_empty ( ) {
1012
- p. span . lo ( )
1041
+ p[ 0 ] . span . lo ( )
1013
1042
} else {
1014
1043
context
1015
1044
. snippet_provider
@@ -1102,7 +1131,7 @@ impl<'a> Rewrite for ControlFlow<'a> {
1102
1131
ast:: ExprKind :: IfLet ( ref pat, ref cond, ref if_block, ref next_else_block) => {
1103
1132
ControlFlow :: new_if (
1104
1133
cond,
1105
- Some ( pat) ,
1134
+ Some ( ptr_vec_to_ref_vec ( pat) ) ,
1106
1135
if_block,
1107
1136
next_else_block. as_ref ( ) . map ( |e| & * * e) ,
1108
1137
false ,
@@ -1455,7 +1484,7 @@ fn rewrite_match_arm(
1455
1484
} ;
1456
1485
let pats_str = rewrite_match_pattern (
1457
1486
context,
1458
- & arm. pats ,
1487
+ & ptr_vec_to_ref_vec ( & arm. pats ) ,
1459
1488
& arm. guard ,
1460
1489
beginning_vert. is_some ( ) ,
1461
1490
shape,
@@ -1513,7 +1542,7 @@ fn is_short_pattern_inner(pat: &ast::Pat) -> bool {
1513
1542
1514
1543
fn rewrite_match_pattern (
1515
1544
context : & RewriteContext ,
1516
- pats : & [ ptr :: P < ast:: Pat > ] ,
1545
+ pats : & [ & ast:: Pat ] ,
1517
1546
guard : & Option < ptr:: P < ast:: Expr > > ,
1518
1547
has_beginning_vert : bool ,
1519
1548
shape : Shape ,
@@ -1524,36 +1553,7 @@ fn rewrite_match_pattern(
1524
1553
let pat_shape = shape
1525
1554
. sub_width ( 5 ) ?
1526
1555
. offset_left ( if has_beginning_vert { 2 } else { 0 } ) ?;
1527
-
1528
- let pat_strs = pats. iter ( )
1529
- . map ( |p| p. rewrite ( context, pat_shape) )
1530
- . collect :: < Option < Vec < _ > > > ( ) ?;
1531
-
1532
- let use_mixed_layout = pats. iter ( )
1533
- . zip ( pat_strs. iter ( ) )
1534
- . all ( |( pat, pat_str) | is_short_pattern ( pat, pat_str) ) ;
1535
- let items: Vec < _ > = pat_strs. into_iter ( ) . map ( ListItem :: from_str) . collect ( ) ;
1536
- let tactic = if use_mixed_layout {
1537
- DefinitiveListTactic :: Mixed
1538
- } else {
1539
- definitive_tactic (
1540
- & items,
1541
- ListTactic :: HorizontalVertical ,
1542
- Separator :: VerticalBar ,
1543
- pat_shape. width ,
1544
- )
1545
- } ;
1546
- let fmt = ListFormatting {
1547
- tactic,
1548
- separator : " |" ,
1549
- trailing_separator : SeparatorTactic :: Never ,
1550
- separator_place : context. config . binop_separator ( ) ,
1551
- shape : pat_shape,
1552
- ends_with_newline : false ,
1553
- preserve_newline : false ,
1554
- config : context. config ,
1555
- } ;
1556
- let pats_str = write_list ( & items, & fmt) ?;
1556
+ let pats_str = rewrite_multiple_patterns ( context, pats, pat_shape) ?;
1557
1557
let beginning_vert = if has_beginning_vert { "| " } else { "" } ;
1558
1558
1559
1559
// Guard
@@ -1749,48 +1749,40 @@ fn rewrite_guard(
1749
1749
}
1750
1750
}
1751
1751
1752
- fn rewrite_pat_expr (
1752
+ fn rewrite_multiple_patterns (
1753
1753
context : & RewriteContext ,
1754
- pat : Option < & ast:: Pat > ,
1755
- expr : & ast:: Expr ,
1756
- matcher : & str ,
1757
- // Connecting piece between pattern and expression,
1758
- // *without* trailing space.
1759
- connector : & str ,
1760
- keyword : & str ,
1754
+ pats : & [ & ast:: Pat ] ,
1761
1755
shape : Shape ,
1762
- offset : usize ,
1763
1756
) -> Option < String > {
1764
- debug ! ( "rewrite_pat_expr {:?} {:?} {:?}" , shape, pat, expr) ;
1765
- let cond_shape = shape. offset_left ( offset) ?;
1766
- if let Some ( pat) = pat {
1767
- let matcher = if matcher. is_empty ( ) {
1768
- matcher. to_owned ( )
1769
- } else {
1770
- format ! ( "{} " , matcher)
1771
- } ;
1772
- let pat_shape = cond_shape
1773
- . offset_left ( matcher. len ( ) ) ?
1774
- . sub_width ( connector. len ( ) ) ?;
1775
- let pat_string = pat. rewrite ( context, pat_shape) ?;
1776
- let result = format ! ( "{}{}{}" , matcher, pat_string, connector) ;
1777
- return rewrite_assign_rhs ( context, result, expr, cond_shape) ;
1778
- }
1779
-
1780
- let expr_rw = expr. rewrite ( context, cond_shape) ;
1781
- // The expression may (partially) fit on the current line.
1782
- // We do not allow splitting between `if` and condition.
1783
- if keyword == "if" || expr_rw. is_some ( ) {
1784
- return expr_rw;
1785
- }
1757
+ let pat_strs = pats. iter ( )
1758
+ . map ( |p| p. rewrite ( context, shape) )
1759
+ . collect :: < Option < Vec < _ > > > ( ) ?;
1786
1760
1787
- // The expression won't fit on the current line, jump to next.
1788
- let nested_shape = shape
1789
- . block_indent ( context. config . tab_spaces ( ) )
1790
- . with_max_width ( context. config ) ;
1791
- let nested_indent_str = nested_shape. indent . to_string_with_newline ( context. config ) ;
1792
- expr. rewrite ( context, nested_shape)
1793
- . map ( |expr_rw| format ! ( "{}{}" , nested_indent_str, expr_rw) )
1761
+ let use_mixed_layout = pats. iter ( )
1762
+ . zip ( pat_strs. iter ( ) )
1763
+ . all ( |( pat, pat_str) | is_short_pattern ( pat, pat_str) ) ;
1764
+ let items: Vec < _ > = pat_strs. into_iter ( ) . map ( ListItem :: from_str) . collect ( ) ;
1765
+ let tactic = if use_mixed_layout {
1766
+ DefinitiveListTactic :: Mixed
1767
+ } else {
1768
+ definitive_tactic (
1769
+ & items,
1770
+ ListTactic :: HorizontalVertical ,
1771
+ Separator :: VerticalBar ,
1772
+ shape. width ,
1773
+ )
1774
+ } ;
1775
+ let fmt = ListFormatting {
1776
+ tactic,
1777
+ separator : " |" ,
1778
+ trailing_separator : SeparatorTactic :: Never ,
1779
+ separator_place : context. config . binop_separator ( ) ,
1780
+ shape : shape,
1781
+ ends_with_newline : false ,
1782
+ preserve_newline : false ,
1783
+ config : context. config ,
1784
+ } ;
1785
+ write_list ( & items, & fmt)
1794
1786
}
1795
1787
1796
1788
fn can_extend_match_arm_body ( body : & ast:: Expr ) -> bool {
0 commit comments