@@ -278,7 +278,7 @@ pub(crate) fn format_expr(
278278 )
279279 . ok ( ) ,
280280 ast:: ExprKind :: Index ( ref expr, ref index, _) => {
281- rewrite_index ( & * * expr, & * * index, context, shape)
281+ rewrite_index ( & * * expr, & * * index, context, shape) . ok ( )
282282 }
283283 ast:: ExprKind :: Repeat ( ref expr, ref repeats) => rewrite_pair (
284284 & * * expr,
@@ -435,7 +435,7 @@ pub(crate) fn format_expr(
435435 } ;
436436
437437 expr_rw
438- . and_then ( |expr_str| recover_comment_removed ( expr_str, expr. span , context) )
438+ . map ( |expr_str| recover_comment_removed ( expr_str, expr. span , context) )
439439 . and_then ( |expr_str| {
440440 let attrs = outer_attributes ( & expr. attrs ) ;
441441 let attrs_str = attrs. rewrite ( context, shape) ?;
@@ -672,6 +672,7 @@ pub(crate) fn rewrite_cond(
672672 String :: from ( "\n " ) + & shape. indent . block_only ( ) . to_string ( context. config ) ;
673673 control_flow
674674 . rewrite_cond ( context, shape, & alt_block_sep)
675+ . ok ( )
675676 . map ( |rw| rw. 0 )
676677 } ) ,
677678 }
@@ -896,20 +897,23 @@ impl<'a> ControlFlow<'a> {
896897 expr : & ast:: Expr ,
897898 shape : Shape ,
898899 offset : usize ,
899- ) -> Option < String > {
900+ ) -> RewriteResult {
900901 debug ! ( "rewrite_pat_expr {:?} {:?} {:?}" , shape, self . pat, expr) ;
901902
902- let cond_shape = shape. offset_left ( offset) ?;
903+ let cond_shape = shape
904+ . offset_left ( offset)
905+ . max_width_error ( shape. width , expr. span ) ?;
903906 if let Some ( pat) = self . pat {
904907 let matcher = if self . matcher . is_empty ( ) {
905908 self . matcher . to_owned ( )
906909 } else {
907910 format ! ( "{} " , self . matcher)
908911 } ;
909912 let pat_shape = cond_shape
910- . offset_left ( matcher. len ( ) ) ?
911- . sub_width ( self . connector . len ( ) ) ?;
912- let pat_string = pat. rewrite ( context, pat_shape) ?;
913+ . offset_left ( matcher. len ( ) )
914+ . and_then ( |s| s. sub_width ( self . connector . len ( ) ) )
915+ . max_width_error ( cond_shape. width , pat. span ) ?;
916+ let pat_string = pat. rewrite_result ( context, pat_shape) ?;
913917 let comments_lo = context
914918 . snippet_provider
915919 . span_after ( self . span . with_lo ( pat. span . hi ( ) ) , self . connector . trim ( ) ) ;
@@ -923,14 +927,13 @@ impl<'a> ControlFlow<'a> {
923927 RhsTactics :: Default ,
924928 comments_span,
925929 true ,
926- )
927- . ok ( ) ;
930+ ) ;
928931 }
929932
930- let expr_rw = expr. rewrite ( context, cond_shape) ;
933+ let expr_rw = expr. rewrite_result ( context, cond_shape) ;
931934 // The expression may (partially) fit on the current line.
932935 // We do not allow splitting between `if` and condition.
933- if self . keyword == "if" || expr_rw. is_some ( ) {
936+ if self . keyword == "if" || expr_rw. is_ok ( ) {
934937 return expr_rw;
935938 }
936939
@@ -939,7 +942,7 @@ impl<'a> ControlFlow<'a> {
939942 . block_indent ( context. config . tab_spaces ( ) )
940943 . with_max_width ( context. config ) ;
941944 let nested_indent_str = nested_shape. indent . to_string_with_newline ( context. config ) ;
942- expr. rewrite ( context, nested_shape)
945+ expr. rewrite_result ( context, nested_shape)
943946 . map ( |expr_rw| format ! ( "{}{}" , nested_indent_str, expr_rw) )
944947 }
945948
@@ -948,7 +951,7 @@ impl<'a> ControlFlow<'a> {
948951 context : & RewriteContext < ' _ > ,
949952 shape : Shape ,
950953 alt_block_sep : & str ,
951- ) -> Option < ( String , usize ) > {
954+ ) -> Result < ( String , usize ) , RewriteError > {
952955 // Do not take the rhs overhead from the upper expressions into account
953956 // when rewriting pattern.
954957 let new_width = context. budget ( shape. used_width ( ) ) ;
@@ -959,7 +962,9 @@ impl<'a> ControlFlow<'a> {
959962 let constr_shape = if self . nested_if {
960963 // We are part of an if-elseif-else chain. Our constraints are tightened.
961964 // 7 = "} else " .len()
962- fresh_shape. offset_left ( 7 ) ?
965+ fresh_shape
966+ . offset_left ( 7 )
967+ . max_width_error ( fresh_shape. width , self . span ) ?
963968 } else {
964969 fresh_shape
965970 } ;
@@ -995,7 +1000,7 @@ impl<'a> ControlFlow<'a> {
9951000
9961001 if let Some ( cond_str) = trial {
9971002 if cond_str. len ( ) <= context. config . single_line_if_else_max_width ( ) {
998- return Some ( ( cond_str, 0 ) ) ;
1003+ return Ok ( ( cond_str, 0 ) ) ;
9991004 }
10001005 }
10011006 }
@@ -1048,7 +1053,7 @@ impl<'a> ControlFlow<'a> {
10481053 label_string. len ( ) + self . keyword . len ( ) + pat_expr_string. len ( ) + 2
10491054 } ;
10501055
1051- Some ( (
1056+ Ok ( (
10521057 format ! (
10531058 "{}{}{}{}{}" ,
10541059 label_string,
@@ -1114,13 +1119,17 @@ pub(crate) fn rewrite_else_kw_with_comments(
11141119
11151120impl < ' a > Rewrite for ControlFlow < ' a > {
11161121 fn rewrite ( & self , context : & RewriteContext < ' _ > , shape : Shape ) -> Option < String > {
1122+ self . rewrite_result ( context, shape) . ok ( )
1123+ }
1124+
1125+ fn rewrite_result ( & self , context : & RewriteContext < ' _ > , shape : Shape ) -> RewriteResult {
11171126 debug ! ( "ControlFlow::rewrite {:?} {:?}" , self , shape) ;
11181127
11191128 let alt_block_sep = & shape. indent . to_string_with_newline ( context. config ) ;
11201129 let ( cond_str, used_width) = self . rewrite_cond ( context, shape, alt_block_sep) ?;
11211130 // If `used_width` is 0, it indicates that whole control flow is written in a single line.
11221131 if used_width == 0 {
1123- return Some ( cond_str) ;
1132+ return Ok ( cond_str) ;
11241133 }
11251134
11261135 let block_width = shape. width . saturating_sub ( used_width) ;
@@ -1138,8 +1147,7 @@ impl<'a> Rewrite for ControlFlow<'a> {
11381147 let block_str = {
11391148 let old_val = context. is_if_else_block . replace ( self . else_block . is_some ( ) ) ;
11401149 let result =
1141- rewrite_block_with_visitor ( context, "" , self . block , None , None , block_shape, true )
1142- . ok ( ) ;
1150+ rewrite_block_with_visitor ( context, "" , self . block , None , None , block_shape, true ) ;
11431151 context. is_if_else_block . replace ( old_val) ;
11441152 result?
11451153 } ;
@@ -1165,7 +1173,7 @@ impl<'a> Rewrite for ControlFlow<'a> {
11651173 true ,
11661174 mk_sp ( else_block. span . lo ( ) , self . span . hi ( ) ) ,
11671175 )
1168- . rewrite ( context, shape)
1176+ . rewrite_result ( context, shape)
11691177 }
11701178 _ => {
11711179 last_in_chain = true ;
@@ -1176,6 +1184,7 @@ impl<'a> Rewrite for ControlFlow<'a> {
11761184 ..shape
11771185 } ;
11781186 format_expr ( else_block, ExprType :: Statement , context, else_shape)
1187+ . unknown_error ( )
11791188 }
11801189 } ;
11811190
@@ -1190,7 +1199,7 @@ impl<'a> Rewrite for ControlFlow<'a> {
11901199 result. push_str ( & rewrite?) ;
11911200 }
11921201
1193- Some ( result)
1202+ Ok ( result)
11941203 }
11951204}
11961205
@@ -1567,8 +1576,8 @@ fn rewrite_index(
15671576 index : & ast:: Expr ,
15681577 context : & RewriteContext < ' _ > ,
15691578 shape : Shape ,
1570- ) -> Option < String > {
1571- let expr_str = expr. rewrite ( context, shape) ?;
1579+ ) -> RewriteResult {
1580+ let expr_str = expr. rewrite_result ( context, shape) ?;
15721581
15731582 let offset = last_line_width ( & expr_str) + 1 ;
15741583 let rhs_overhead = shape. rhs_overhead ( context. config ) ;
@@ -1583,37 +1592,45 @@ fn rewrite_index(
15831592 . and_then ( |shape| shape. sub_width ( 1 ) ) ,
15841593 IndentStyle :: Visual => shape. visual_indent ( offset) . sub_width ( offset + 1 ) ,
15851594 }
1586- } ;
1587- let orig_index_rw = index_shape. and_then ( |s| index. rewrite ( context, s) ) ;
1595+ }
1596+ . max_width_error ( shape. width , index. span ( ) ) ;
1597+ let orig_index_rw = index_shape. and_then ( |s| index. rewrite_result ( context, s) ) ;
15881598
15891599 // Return if index fits in a single line.
15901600 match orig_index_rw {
1591- Some ( ref index_str) if !index_str. contains ( '\n' ) => {
1592- return Some ( format ! ( "{expr_str}[{index_str}]" ) ) ;
1601+ Ok ( ref index_str) if !index_str. contains ( '\n' ) => {
1602+ return Ok ( format ! ( "{expr_str}[{index_str}]" ) ) ;
15931603 }
15941604 _ => ( ) ,
15951605 }
15961606
15971607 // Try putting index on the next line and see if it fits in a single line.
15981608 let indent = shape. indent . block_indent ( context. config ) ;
1599- let index_shape = Shape :: indented ( indent, context. config ) . offset_left ( 1 ) ?;
1600- let index_shape = index_shape. sub_width ( 1 + rhs_overhead) ?;
1601- let new_index_rw = index. rewrite ( context, index_shape) ;
1609+ let index_shape = Shape :: indented ( indent, context. config )
1610+ . offset_left ( 1 )
1611+ . max_width_error ( shape. width , index. span ( ) ) ?;
1612+ let index_shape = index_shape
1613+ . sub_width ( 1 + rhs_overhead)
1614+ . max_width_error ( index_shape. width , index. span ( ) ) ?;
1615+ let new_index_rw = index. rewrite_result ( context, index_shape) ;
16021616 match ( orig_index_rw, new_index_rw) {
1603- ( _, Some ( ref new_index_str) ) if !new_index_str. contains ( '\n' ) => Some ( format ! (
1617+ ( _, Ok ( ref new_index_str) ) if !new_index_str. contains ( '\n' ) => Ok ( format ! (
16041618 "{}{}[{}]" ,
16051619 expr_str,
16061620 indent. to_string_with_newline( context. config) ,
16071621 new_index_str,
16081622 ) ) ,
1609- ( None , Some ( ref new_index_str) ) => Some ( format ! (
1623+ ( Err ( _ ) , Ok ( ref new_index_str) ) => Ok ( format ! (
16101624 "{}{}[{}]" ,
16111625 expr_str,
16121626 indent. to_string_with_newline( context. config) ,
16131627 new_index_str,
16141628 ) ) ,
1615- ( Some ( ref index_str) , _) => Some ( format ! ( "{expr_str}[{index_str}]" ) ) ,
1616- _ => None ,
1629+ ( Ok ( ref index_str) , _) => Ok ( format ! ( "{expr_str}[{index_str}]" ) ) ,
1630+ // When both orig_index_rw and new_index_rw result in errors, we currently propagate the
1631+ // error from the second attempt since it is more generous with width constraints.
1632+ // This decision is somewhat arbitrary and is open to change.
1633+ ( Err ( _) , Err ( new_index_rw_err) ) => Err ( new_index_rw_err) ,
16171634 }
16181635}
16191636
0 commit comments