@@ -9,7 +9,7 @@ use crate::expr::{block_contains_comment, is_simple_block, is_unsafe_block, rewr
99use crate :: items:: { span_hi_for_param, span_lo_for_param} ;
1010use crate :: lists:: { definitive_tactic, itemize_list, write_list, ListFormatting , Separator } ;
1111use crate :: overflow:: OverflowableItem ;
12- use crate :: rewrite:: { Rewrite , RewriteContext } ;
12+ use crate :: rewrite:: { Rewrite , RewriteContext , RewriteError , RewriteErrorExt , RewriteResult } ;
1313use crate :: shape:: Shape ;
1414use crate :: source_map:: SpanUtils ;
1515use crate :: types:: rewrite_bound_params;
@@ -36,7 +36,7 @@ pub(crate) fn rewrite_closure(
3636 span : Span ,
3737 context : & RewriteContext < ' _ > ,
3838 shape : Shape ,
39- ) -> Option < String > {
39+ ) -> RewriteResult {
4040 debug ! ( "rewrite_closure {:?}" , body) ;
4141
4242 let ( prefix, extra_offset) = rewrite_closure_fn_decl (
@@ -52,29 +52,31 @@ pub(crate) fn rewrite_closure(
5252 shape,
5353 ) ?;
5454 // 1 = space between `|...|` and body.
55- let body_shape = shape. offset_left ( extra_offset) ?;
55+ let body_shape = shape
56+ . offset_left ( extra_offset)
57+ . max_width_error ( shape. width , span) ?;
5658
5759 if let ast:: ExprKind :: Block ( ref block, _) = body. kind {
5860 // The body of the closure is an empty block.
5961 if block. stmts . is_empty ( ) && !block_contains_comment ( context, block) {
6062 return body
61- . rewrite ( context, shape)
63+ . rewrite_result ( context, shape)
6264 . map ( |s| format ! ( "{} {}" , prefix, s) ) ;
6365 }
6466
6567 let result = match fn_decl. output {
6668 ast:: FnRetTy :: Default ( _) if !context. inside_macro ( ) => {
6769 try_rewrite_without_block ( body, & prefix, context, shape, body_shape)
6870 }
69- _ => None ,
71+ _ => Err ( RewriteError :: Unknown ) ,
7072 } ;
7173
72- result. or_else ( || {
74+ result. or_else ( |_ | {
7375 // Either we require a block, or tried without and failed.
7476 rewrite_closure_block ( block, & prefix, context, body_shape)
7577 } )
7678 } else {
77- rewrite_closure_expr ( body, & prefix, context, body_shape) . or_else ( || {
79+ rewrite_closure_expr ( body, & prefix, context, body_shape) . or_else ( |_ | {
7880 // The closure originally had a non-block expression, but we can't fit on
7981 // one line, so we'll insert a block.
8082 rewrite_closure_with_block ( body, & prefix, context, body_shape)
@@ -88,7 +90,7 @@ fn try_rewrite_without_block(
8890 context : & RewriteContext < ' _ > ,
8991 shape : Shape ,
9092 body_shape : Shape ,
91- ) -> Option < String > {
93+ ) -> RewriteResult {
9294 let expr = get_inner_expr ( expr, prefix, context) ;
9395
9496 if is_block_closure_forced ( context, expr) {
@@ -152,11 +154,11 @@ fn rewrite_closure_with_block(
152154 prefix : & str ,
153155 context : & RewriteContext < ' _ > ,
154156 shape : Shape ,
155- ) -> Option < String > {
157+ ) -> RewriteResult {
156158 let left_most = left_most_sub_expr ( body) ;
157159 let veto_block = veto_block ( body) && !expr_requires_semi_to_be_stmt ( left_most) ;
158160 if veto_block {
159- return None ;
161+ return Err ( RewriteError :: Unknown ) ;
160162 }
161163
162164 let block = ast:: Block {
@@ -183,9 +185,8 @@ fn rewrite_closure_with_block(
183185 None ,
184186 shape,
185187 false ,
186- )
187- . ok ( ) ?;
188- Some ( format ! ( "{prefix} {block}" ) )
188+ ) ?;
189+ Ok ( format ! ( "{prefix} {block}" ) )
189190}
190191
191192// Rewrite closure with a single expression without wrapping its body with block.
@@ -194,7 +195,7 @@ fn rewrite_closure_expr(
194195 prefix : & str ,
195196 context : & RewriteContext < ' _ > ,
196197 shape : Shape ,
197- ) -> Option < String > {
198+ ) -> RewriteResult {
198199 fn allow_multi_line ( expr : & ast:: Expr ) -> bool {
199200 match expr. kind {
200201 ast:: ExprKind :: Match ( ..)
@@ -217,12 +218,12 @@ fn rewrite_closure_expr(
217218 // unless it is a block-like expression or we are inside macro call.
218219 let veto_multiline = ( !allow_multi_line ( expr) && !context. inside_macro ( ) )
219220 || context. config . force_multiline_blocks ( ) ;
220- expr. rewrite ( context, shape)
221+ expr. rewrite_result ( context, shape)
221222 . and_then ( |rw| {
222223 if veto_multiline && rw. contains ( '\n' ) {
223- None
224+ Err ( RewriteError :: Unknown )
224225 } else {
225- Some ( rw)
226+ Ok ( rw)
226227 }
227228 } )
228229 . map ( |rw| format ! ( "{} {}" , prefix, rw) )
@@ -234,8 +235,12 @@ fn rewrite_closure_block(
234235 prefix : & str ,
235236 context : & RewriteContext < ' _ > ,
236237 shape : Shape ,
237- ) -> Option < String > {
238- Some ( format ! ( "{} {}" , prefix, block. rewrite( context, shape) ?) )
238+ ) -> RewriteResult {
239+ Ok ( format ! (
240+ "{} {}" ,
241+ prefix,
242+ block. rewrite_result( context, shape) ?
243+ ) )
239244}
240245
241246// Return type is (prefix, extra_offset)
@@ -250,13 +255,14 @@ fn rewrite_closure_fn_decl(
250255 span : Span ,
251256 context : & RewriteContext < ' _ > ,
252257 shape : Shape ,
253- ) -> Option < ( String , usize ) > {
258+ ) -> Result < ( String , usize ) , RewriteError > {
254259 let binder = match binder {
255260 ast:: ClosureBinder :: For { generic_params, .. } if generic_params. is_empty ( ) => {
256261 "for<> " . to_owned ( )
257262 }
258263 ast:: ClosureBinder :: For { generic_params, .. } => {
259- let lifetime_str = rewrite_bound_params ( context, shape, generic_params) ?;
264+ let lifetime_str =
265+ rewrite_bound_params ( context, shape, generic_params) . unknown_error ( ) ?;
260266 format ! ( "for<{lifetime_str}> " )
261267 }
262268 ast:: ClosureBinder :: NotPresent => "" . to_owned ( ) ,
@@ -287,13 +293,17 @@ fn rewrite_closure_fn_decl(
287293 // 4 = "|| {".len(), which is overconservative when the closure consists of
288294 // a single expression.
289295 let nested_shape = shape
290- . shrink_left ( binder. len ( ) + const_. len ( ) + immovable. len ( ) + coro. len ( ) + mover. len ( ) ) ?
291- . sub_width ( 4 ) ?;
296+ . shrink_left ( binder. len ( ) + const_. len ( ) + immovable. len ( ) + coro. len ( ) + mover. len ( ) )
297+ . and_then ( |shape| shape. sub_width ( 4 ) )
298+ . max_width_error ( shape. width , span) ?;
292299
293300 // 1 = |
294301 let param_offset = nested_shape. indent + 1 ;
295- let param_shape = nested_shape. offset_left ( 1 ) ?. visual_indent ( 0 ) ;
296- let ret_str = fn_decl. output . rewrite ( context, param_shape) ?;
302+ let param_shape = nested_shape
303+ . offset_left ( 1 )
304+ . max_width_error ( nested_shape. width , span) ?
305+ . visual_indent ( 0 ) ;
306+ let ret_str = fn_decl. output . rewrite_result ( context, param_shape) ?;
297307
298308 let param_items = itemize_list (
299309 context. snippet_provider ,
@@ -317,14 +327,16 @@ fn rewrite_closure_fn_decl(
317327 horizontal_budget,
318328 ) ;
319329 let param_shape = match tactic {
320- DefinitiveListTactic :: Horizontal => param_shape. sub_width ( ret_str. len ( ) + 1 ) ?,
330+ DefinitiveListTactic :: Horizontal => param_shape
331+ . sub_width ( ret_str. len ( ) + 1 )
332+ . max_width_error ( param_shape. width , span) ?,
321333 _ => param_shape,
322334 } ;
323335
324336 let fmt = ListFormatting :: new ( param_shape, context. config )
325337 . tactic ( tactic)
326338 . preserve_newline ( true ) ;
327- let list_str = write_list ( & item_vec, & fmt) ?;
339+ let list_str = write_list ( & item_vec, & fmt) . unknown_error ( ) ?;
328340 let mut prefix = format ! ( "{binder}{const_}{immovable}{coro}{mover}|{list_str}|" ) ;
329341
330342 if !ret_str. is_empty ( ) {
@@ -339,7 +351,7 @@ fn rewrite_closure_fn_decl(
339351 // 1 = space between `|...|` and body.
340352 let extra_offset = last_line_width ( & prefix) + 1 ;
341353
342- Some ( ( prefix, extra_offset) )
354+ Ok ( ( prefix, extra_offset) )
343355}
344356
345357// Rewriting closure which is placed at the end of the function call's arg.
@@ -348,7 +360,7 @@ pub(crate) fn rewrite_last_closure(
348360 context : & RewriteContext < ' _ > ,
349361 expr : & ast:: Expr ,
350362 shape : Shape ,
351- ) -> Option < String > {
363+ ) -> RewriteResult {
352364 if let ast:: ExprKind :: Closure ( ref closure) = expr. kind {
353365 let ast:: Closure {
354366 ref binder,
@@ -385,10 +397,12 @@ pub(crate) fn rewrite_last_closure(
385397 ) ?;
386398 // If the closure goes multi line before its body, do not overflow the closure.
387399 if prefix. contains ( '\n' ) {
388- return None ;
400+ return Err ( RewriteError :: Unknown ) ;
389401 }
390402
391- let body_shape = shape. offset_left ( extra_offset) ?;
403+ let body_shape = shape
404+ . offset_left ( extra_offset)
405+ . max_width_error ( shape. width , expr. span ) ?;
392406
393407 // We force to use block for the body of the closure for certain kinds of expressions.
394408 if is_block_closure_forced ( context, body) {
@@ -400,7 +414,7 @@ pub(crate) fn rewrite_last_closure(
400414 // closure. However, if the closure has a return type, then we must
401415 // keep the blocks.
402416 match rewrite_closure_expr ( body, & prefix, context, shape) {
403- Some ( single_line_body_str)
417+ Ok ( single_line_body_str)
404418 if !single_line_body_str. contains ( '\n' ) =>
405419 {
406420 single_line_body_str
@@ -424,9 +438,9 @@ pub(crate) fn rewrite_last_closure(
424438 }
425439
426440 // Seems fine, just format the closure in usual manner.
427- return expr. rewrite ( context, shape) ;
441+ return expr. rewrite_result ( context, shape) ;
428442 }
429- None
443+ Err ( RewriteError :: Unknown )
430444}
431445
432446/// Returns `true` if the given vector of arguments has more than one `ast::ExprKind::Closure`.
0 commit comments