@@ -13,7 +13,7 @@ use crate::expr::{
13
13
ExprType , RhsTactics ,
14
14
} ;
15
15
use crate :: lists:: { itemize_list, write_list, ListFormatting } ;
16
- use crate :: rewrite:: { Rewrite , RewriteContext } ;
16
+ use crate :: rewrite:: { Rewrite , RewriteContext , RewriteError , RewriteErrorExt , RewriteResult } ;
17
17
use crate :: shape:: Shape ;
18
18
use crate :: source_map:: SpanUtils ;
19
19
use crate :: spanned:: Spanned ;
@@ -55,6 +55,10 @@ impl<'a> Spanned for ArmWrapper<'a> {
55
55
56
56
impl < ' a > Rewrite for ArmWrapper < ' a > {
57
57
fn rewrite ( & self , context : & RewriteContext < ' _ > , shape : Shape ) -> Option < String > {
58
+ self . rewrite_result ( context, shape) . ok ( )
59
+ }
60
+
61
+ fn rewrite_result ( & self , context : & RewriteContext < ' _ > , shape : Shape ) -> RewriteResult {
58
62
rewrite_match_arm (
59
63
context,
60
64
self . arm ,
@@ -73,7 +77,7 @@ pub(crate) fn rewrite_match(
73
77
span : Span ,
74
78
attrs : & [ ast:: Attribute ] ,
75
79
match_kind : MatchKind ,
76
- ) -> Option < String > {
80
+ ) -> RewriteResult {
77
81
// Do not take the rhs overhead from the upper expressions into account
78
82
// when rewriting match condition.
79
83
let cond_shape = Shape {
@@ -82,10 +86,14 @@ pub(crate) fn rewrite_match(
82
86
} ;
83
87
// 6 = `match `
84
88
let cond_shape = match context. config . indent_style ( ) {
85
- IndentStyle :: Visual => cond_shape. shrink_left ( 6 ) ?,
86
- IndentStyle :: Block => cond_shape. offset_left ( 6 ) ?,
89
+ IndentStyle :: Visual => cond_shape
90
+ . shrink_left ( 6 )
91
+ . max_width_error ( shape. width , span) ?,
92
+ IndentStyle :: Block => cond_shape
93
+ . offset_left ( 6 )
94
+ . max_width_error ( shape. width , span) ?,
87
95
} ;
88
- let cond_str = cond. rewrite ( context, cond_shape) ?;
96
+ let cond_str = cond. rewrite_result ( context, cond_shape) ?;
89
97
let alt_block_sep = & shape. indent . to_string_with_newline ( context. config ) ;
90
98
let block_sep = match context. config . control_brace_style ( ) {
91
99
ControlBraceStyle :: AlwaysNextLine => alt_block_sep,
@@ -109,7 +117,7 @@ pub(crate) fn rewrite_match(
109
117
_ => shape. block_indent ( context. config . tab_spaces ( ) ) ,
110
118
} ;
111
119
inner_attrs
112
- . rewrite ( context, shape)
120
+ . rewrite_result ( context, shape)
113
121
. map ( |s| format ! ( "{}{}\n " , nested_indent_str, s) ) ?
114
122
} ;
115
123
@@ -129,16 +137,16 @@ pub(crate) fn rewrite_match(
129
137
if arms. is_empty ( ) {
130
138
let snippet = context. snippet ( mk_sp ( open_brace_pos, span. hi ( ) - BytePos ( 1 ) ) ) ;
131
139
if snippet. trim ( ) . is_empty ( ) {
132
- Some ( format ! ( "match {cond_str} {{}}" ) )
140
+ Ok ( format ! ( "match {cond_str} {{}}" ) )
133
141
} else {
134
142
// Empty match with comments or inner attributes? We are not going to bother, sorry ;)
135
- Some ( context. snippet ( span) . to_owned ( ) )
143
+ Ok ( context. snippet ( span) . to_owned ( ) )
136
144
}
137
145
} else {
138
146
let span_after_cond = mk_sp ( cond. span . hi ( ) , span. hi ( ) ) ;
139
147
140
148
match match_kind {
141
- MatchKind :: Prefix => Some ( format ! (
149
+ MatchKind :: Prefix => Ok ( format ! (
142
150
"match {}{}{{\n {}{}{}\n {}}}" ,
143
151
cond_str,
144
152
block_sep,
@@ -147,7 +155,7 @@ pub(crate) fn rewrite_match(
147
155
rewrite_match_arms( context, arms, shape, span_after_cond, open_brace_pos) ?,
148
156
shape. indent. to_string( context. config) ,
149
157
) ) ,
150
- MatchKind :: Postfix => Some ( format ! (
158
+ MatchKind :: Postfix => Ok ( format ! (
151
159
"{}.match{}{{\n {}{}{}\n {}}}" ,
152
160
cond_str,
153
161
block_sep,
@@ -197,7 +205,7 @@ fn rewrite_match_arms(
197
205
shape : Shape ,
198
206
span : Span ,
199
207
open_brace_pos : BytePos ,
200
- ) -> Option < String > {
208
+ ) -> RewriteResult {
201
209
let arm_shape = shape
202
210
. block_indent ( context. config . tab_spaces ( ) )
203
211
. with_max_width ( context. config ) ;
@@ -228,7 +236,7 @@ fn rewrite_match_arms(
228
236
. separator ( "" )
229
237
. preserve_newline ( true ) ;
230
238
231
- write_list ( & arms_vec, & fmt)
239
+ write_list ( & arms_vec, & fmt) . unknown_error ( )
232
240
}
233
241
234
242
fn rewrite_match_arm (
@@ -237,19 +245,19 @@ fn rewrite_match_arm(
237
245
shape : Shape ,
238
246
is_last : bool ,
239
247
has_leading_pipe : bool ,
240
- ) -> Option < String > {
248
+ ) -> RewriteResult {
241
249
let ( missing_span, attrs_str) = if !arm. attrs . is_empty ( ) {
242
250
if contains_skip ( & arm. attrs ) {
243
- let ( _, body) = flatten_arm_body ( context, arm. body . as_deref ( ) ?, None ) ;
251
+ let ( _, body) = flatten_arm_body ( context, arm. body . as_deref ( ) . unknown_error ( ) ?, None ) ;
244
252
// `arm.span()` does not include trailing comma, add it manually.
245
- return Some ( format ! (
253
+ return Ok ( format ! (
246
254
"{}{}" ,
247
255
context. snippet( arm. span( ) ) ,
248
256
arm_comma( context. config, body, is_last) ,
249
257
) ) ;
250
258
}
251
259
let missing_span = mk_sp ( arm. attrs [ arm. attrs . len ( ) - 1 ] . span . hi ( ) , arm. pat . span . lo ( ) ) ;
252
- ( missing_span, arm. attrs . rewrite ( context, shape) ?)
260
+ ( missing_span, arm. attrs . rewrite_result ( context, shape) ?)
253
261
} else {
254
262
( mk_sp ( arm. span ( ) . lo ( ) , arm. span ( ) . lo ( ) ) , String :: new ( ) )
255
263
} ;
@@ -263,19 +271,25 @@ fn rewrite_match_arm(
263
271
} ;
264
272
265
273
// Patterns
266
- let pat_shape = match & arm. body . as_ref ( ) ?. kind {
274
+ let pat_shape = match & arm. body . as_ref ( ) . unknown_error ( ) ?. kind {
267
275
ast:: ExprKind :: Block ( _, Some ( label) ) => {
268
276
// Some block with a label ` => 'label: {`
269
277
// 7 = ` => : {`
270
278
let label_len = label. ident . as_str ( ) . len ( ) ;
271
- shape. sub_width ( 7 + label_len) ?. offset_left ( pipe_offset) ?
279
+ shape
280
+ . sub_width ( 7 + label_len)
281
+ . and_then ( |s| s. offset_left ( pipe_offset) )
282
+ . max_width_error ( shape. width , arm. span ) ?
272
283
}
273
284
_ => {
274
285
// 5 = ` => {`
275
- shape. sub_width ( 5 ) ?. offset_left ( pipe_offset) ?
286
+ shape
287
+ . sub_width ( 5 )
288
+ . and_then ( |s| s. offset_left ( pipe_offset) )
289
+ . max_width_error ( shape. width , arm. span ) ?
276
290
}
277
291
} ;
278
- let pats_str = arm. pat . rewrite ( context, pat_shape) ?;
292
+ let pats_str = arm. pat . rewrite_result ( context, pat_shape) ?;
279
293
280
294
// Guard
281
295
let block_like_pat = trimmed_last_line_width ( & pats_str) <= context. config . tab_spaces ( ) ;
@@ -295,12 +309,16 @@ fn rewrite_match_arm(
295
309
missing_span,
296
310
shape,
297
311
false ,
298
- ) ?;
312
+ )
313
+ . unknown_error ( ) ?;
299
314
300
- let arrow_span = mk_sp ( arm. pat . span . hi ( ) , arm. body . as_ref ( ) ?. span ( ) . lo ( ) ) ;
315
+ let arrow_span = mk_sp (
316
+ arm. pat . span . hi ( ) ,
317
+ arm. body . as_ref ( ) . unknown_error ( ) ?. span ( ) . lo ( ) ,
318
+ ) ;
301
319
rewrite_match_body (
302
320
context,
303
- arm. body . as_ref ( ) ?,
321
+ arm. body . as_ref ( ) . unknown_error ( ) ?,
304
322
& lhs_str,
305
323
shape,
306
324
guard_str. contains ( '\n' ) ,
@@ -381,7 +399,7 @@ fn rewrite_match_body(
381
399
has_guard : bool ,
382
400
arrow_span : Span ,
383
401
is_last : bool ,
384
- ) -> Option < String > {
402
+ ) -> RewriteResult {
385
403
let ( extend, body) = flatten_arm_body (
386
404
context,
387
405
body,
@@ -402,7 +420,7 @@ fn rewrite_match_body(
402
420
_ => " " ,
403
421
} ;
404
422
405
- Some ( format ! ( "{} =>{}{}{}" , pats_str, block_sep, body_str, comma) )
423
+ Ok ( format ! ( "{} =>{}{}{}" , pats_str, block_sep, body_str, comma) )
406
424
} ;
407
425
408
426
let next_line_indent = if !is_block || is_empty_block {
@@ -429,7 +447,7 @@ fn rewrite_match_body(
429
447
if comment_str. is_empty ( ) {
430
448
String :: new ( )
431
449
} else {
432
- rewrite_comment ( comment_str, false , shape, context. config ) ?
450
+ rewrite_comment ( comment_str, false , shape, context. config ) . unknown_error ( ) ?
433
451
}
434
452
} ;
435
453
@@ -446,7 +464,7 @@ fn rewrite_match_body(
446
464
result. push_str ( & nested_indent_str) ;
447
465
result. push_str ( body_str) ;
448
466
result. push_str ( comma) ;
449
- return Some ( result) ;
467
+ return Ok ( result) ;
450
468
}
451
469
452
470
let indent_str = shape. indent . to_string_with_newline ( context. config ) ;
@@ -489,7 +507,7 @@ fn rewrite_match_body(
489
507
result. push_str ( & block_sep) ;
490
508
result. push_str ( body_str) ;
491
509
result. push_str ( & body_suffix) ;
492
- Some ( result)
510
+ Ok ( result)
493
511
} ;
494
512
495
513
// Let's try and get the arm body on the same line as the condition.
@@ -539,7 +557,7 @@ fn rewrite_match_body(
539
557
combine_next_line_body ( next_line_str)
540
558
}
541
559
( None , Some ( ref next_line_str) ) => combine_next_line_body ( next_line_str) ,
542
- ( None , None ) => None ,
560
+ ( None , None ) => Err ( RewriteError :: Unknown ) ,
543
561
( Some ( ref orig_str) , _) => combine_orig_body ( orig_str) ,
544
562
}
545
563
}
@@ -553,7 +571,7 @@ fn rewrite_guard(
553
571
// the arm (excludes offset).
554
572
pattern_width : usize ,
555
573
multiline_pattern : bool ,
556
- ) -> Option < String > {
574
+ ) -> RewriteResult {
557
575
if let Some ( ref guard) = * guard {
558
576
// First try to fit the guard string on the same line as the pattern.
559
577
// 4 = ` if `, 5 = ` => {`
@@ -562,9 +580,9 @@ fn rewrite_guard(
562
580
. and_then ( |s| s. sub_width ( 5 ) ) ;
563
581
if !multiline_pattern {
564
582
if let Some ( cond_shape) = cond_shape {
565
- if let Some ( cond_str) = guard. rewrite ( context, cond_shape) {
583
+ if let Ok ( cond_str) = guard. rewrite_result ( context, cond_shape) {
566
584
if !cond_str. contains ( '\n' ) || pattern_width <= context. config . tab_spaces ( ) {
567
- return Some ( format ! ( " if {cond_str}" ) ) ;
585
+ return Ok ( format ! ( " if {cond_str}" ) ) ;
568
586
}
569
587
}
570
588
}
@@ -574,20 +592,16 @@ fn rewrite_guard(
574
592
// 3 = `if `, 5 = ` => {`
575
593
let cond_shape = Shape :: indented ( shape. indent . block_indent ( context. config ) , context. config )
576
594
. offset_left ( 3 )
577
- . and_then ( |s| s. sub_width ( 5 ) ) ;
578
- if let Some ( cond_shape) = cond_shape {
579
- if let Some ( cond_str) = guard. rewrite ( context, cond_shape) {
580
- return Some ( format ! (
581
- "{}if {}" ,
582
- cond_shape. indent. to_string_with_newline( context. config) ,
583
- cond_str
584
- ) ) ;
585
- }
586
- }
587
-
588
- None
595
+ . and_then ( |s| s. sub_width ( 5 ) )
596
+ . max_width_error ( shape. width , guard. span ) ?;
597
+ let cond_str = guard. rewrite_result ( context, cond_shape) ?;
598
+ Ok ( format ! (
599
+ "{}if {}" ,
600
+ cond_shape. indent. to_string_with_newline( context. config) ,
601
+ cond_str
602
+ ) )
589
603
} else {
590
- Some ( String :: new ( ) )
604
+ Ok ( String :: new ( ) )
591
605
}
592
606
}
593
607
0 commit comments