@@ -693,7 +693,7 @@ pub(crate) fn format_impl(
693
693
{
694
694
option. suppress_comma ( ) ;
695
695
option. snuggle ( ) ;
696
- option. compress_where ( ) ;
696
+ option. allow_single_line ( ) ;
697
697
}
698
698
699
699
let misssing_span = mk_sp ( self_ty. span . hi ( ) , item. span . hi ( ) ) ;
@@ -708,7 +708,6 @@ pub(crate) fn format_impl(
708
708
where_span_end,
709
709
self_ty. span . hi ( ) ,
710
710
option,
711
- false ,
712
711
) ?;
713
712
714
713
// If there is no where-clause, we may have missing comments between the trait name and
@@ -1068,7 +1067,6 @@ pub(crate) fn format_trait(
1068
1067
None ,
1069
1068
pos_before_where,
1070
1069
option,
1071
- false ,
1072
1070
) ?;
1073
1071
// If the where-clause cannot fit on the same line,
1074
1072
// put the where-clause on a new line
@@ -1376,7 +1374,7 @@ fn format_tuple_struct(
1376
1374
result. push_str ( & generics_str) ;
1377
1375
1378
1376
let where_budget = context. budget ( last_line_width ( & result) ) ;
1379
- let option = WhereClauseOption :: new ( true , false ) ;
1377
+ let option = WhereClauseOption :: new ( true , WhereClauseSpace :: Newline ) ;
1380
1378
rewrite_where_clause (
1381
1379
context,
1382
1380
& generics. where_clause ,
@@ -1387,7 +1385,6 @@ fn format_tuple_struct(
1387
1385
None ,
1388
1386
body_hi,
1389
1387
option,
1390
- false ,
1391
1388
) ?
1392
1389
}
1393
1390
None => "" . to_owned ( ) ,
@@ -1464,7 +1461,6 @@ fn rewrite_type_prefix(
1464
1461
None ,
1465
1462
generics. span . hi ( ) ,
1466
1463
option,
1467
- false ,
1468
1464
) ?;
1469
1465
result. push_str ( & where_clause_str) ;
1470
1466
@@ -2205,7 +2201,15 @@ fn rewrite_fn_base(
2205
2201
2206
2202
let is_args_multi_lined = arg_str. contains ( '\n' ) ;
2207
2203
2208
- let option = WhereClauseOption :: new ( !has_body, put_args_in_block && ret_str. is_empty ( ) ) ;
2204
+ let space = if put_args_in_block && ret_str. is_empty ( ) {
2205
+ WhereClauseSpace :: Space
2206
+ } else {
2207
+ WhereClauseSpace :: Newline
2208
+ } ;
2209
+ let mut option = WhereClauseOption :: new ( !has_body, space) ;
2210
+ if is_args_multi_lined {
2211
+ option. veto_single_line ( ) ;
2212
+ }
2209
2213
let where_clause_str = rewrite_where_clause (
2210
2214
context,
2211
2215
where_clause,
@@ -2216,7 +2220,6 @@ fn rewrite_fn_base(
2216
2220
Some ( span. hi ( ) ) ,
2217
2221
pos_before_where,
2218
2222
option,
2219
- is_args_multi_lined,
2220
2223
) ?;
2221
2224
// If there are neither where-clause nor return type, we may be missing comments between
2222
2225
// args and `{`.
@@ -2244,40 +2247,62 @@ fn rewrite_fn_base(
2244
2247
Some ( ( result, force_new_line_for_brace) )
2245
2248
}
2246
2249
2250
+ /// Kind of spaces to put before `where`.
2251
+ #[ derive( Copy , Clone ) ]
2252
+ enum WhereClauseSpace {
2253
+ /// A single space.
2254
+ Space ,
2255
+ /// A new line.
2256
+ Newline ,
2257
+ /// Nothing.
2258
+ None ,
2259
+ }
2260
+
2247
2261
#[ derive( Copy , Clone ) ]
2248
2262
struct WhereClauseOption {
2249
2263
suppress_comma : bool , // Force no trailing comma
2250
- snuggle : bool , // Do not insert newline before `where`
2251
- compress_where : bool , // Try single line where-clause instead of vertical layout
2264
+ snuggle : WhereClauseSpace ,
2265
+ allow_single_line : bool , // Try single line where-clause instead of vertical layout
2266
+ veto_single_line : bool , // Disallow a single-line where-clause.
2252
2267
}
2253
2268
2254
2269
impl WhereClauseOption {
2255
- fn new ( suppress_comma : bool , snuggle : bool ) -> WhereClauseOption {
2270
+ fn new ( suppress_comma : bool , snuggle : WhereClauseSpace ) -> WhereClauseOption {
2256
2271
WhereClauseOption {
2257
2272
suppress_comma,
2258
2273
snuggle,
2259
- compress_where : false ,
2274
+ allow_single_line : false ,
2275
+ veto_single_line : false ,
2260
2276
}
2261
2277
}
2262
2278
2263
2279
fn snuggled ( current : & str ) -> WhereClauseOption {
2264
2280
WhereClauseOption {
2265
2281
suppress_comma : false ,
2266
- snuggle : last_line_width ( current) == 1 ,
2267
- compress_where : false ,
2282
+ snuggle : if last_line_width ( current) == 1 {
2283
+ WhereClauseSpace :: Space
2284
+ } else {
2285
+ WhereClauseSpace :: Newline
2286
+ } ,
2287
+ allow_single_line : false ,
2288
+ veto_single_line : false ,
2268
2289
}
2269
2290
}
2270
2291
2271
2292
fn suppress_comma ( & mut self ) {
2272
2293
self . suppress_comma = true
2273
2294
}
2274
2295
2275
- fn compress_where ( & mut self ) {
2276
- self . compress_where = true
2296
+ fn allow_single_line ( & mut self ) {
2297
+ self . allow_single_line = true
2277
2298
}
2278
2299
2279
2300
fn snuggle ( & mut self ) {
2280
- self . snuggle = true
2301
+ self . snuggle = WhereClauseSpace :: Space
2302
+ }
2303
+
2304
+ fn veto_single_line ( & mut self ) {
2305
+ self . veto_single_line = true ;
2281
2306
}
2282
2307
}
2283
2308
@@ -2467,25 +2492,104 @@ fn rewrite_where_clause_rfc_style(
2467
2492
span_end : Option < BytePos > ,
2468
2493
span_end_before_where : BytePos ,
2469
2494
where_clause_option : WhereClauseOption ,
2470
- is_args_multi_line : bool ,
2471
2495
) -> Option < String > {
2496
+ let ( where_keyword, allow_single_line) = rewrite_where_keyword (
2497
+ context,
2498
+ where_clause,
2499
+ shape,
2500
+ span_end_before_where,
2501
+ where_clause_option,
2502
+ ) ?;
2503
+
2504
+ // 1 = `,`
2505
+ let clause_shape = shape
2506
+ . block ( )
2507
+ . with_max_width ( context. config )
2508
+ . block_left ( context. config . tab_spaces ( ) ) ?
2509
+ . sub_width ( 1 ) ?;
2510
+ let force_single_line = context. config . where_single_line ( )
2511
+ && where_clause. predicates . len ( ) == 1
2512
+ && !where_clause_option. veto_single_line ;
2513
+
2514
+ let preds_str = rewrite_bounds_on_where_clause (
2515
+ context,
2516
+ where_clause,
2517
+ clause_shape,
2518
+ terminator,
2519
+ span_end,
2520
+ where_clause_option,
2521
+ force_single_line,
2522
+ ) ?;
2523
+
2524
+ // 6 = `where `
2525
+ let clause_sep =
2526
+ if allow_single_line && !preds_str. contains ( '\n' ) && 6 + preds_str. len ( ) <= shape. width
2527
+ || force_single_line
2528
+ {
2529
+ Cow :: from ( " " )
2530
+ } else {
2531
+ clause_shape. indent . to_string_with_newline ( context. config )
2532
+ } ;
2533
+
2534
+ Some ( format ! ( "{}{}{}" , where_keyword, clause_sep, preds_str) )
2535
+ }
2536
+
2537
+ /// Rewrite `where` and comment around it.
2538
+ fn rewrite_where_keyword (
2539
+ context : & RewriteContext < ' _ > ,
2540
+ where_clause : & ast:: WhereClause ,
2541
+ shape : Shape ,
2542
+ span_end_before_where : BytePos ,
2543
+ where_clause_option : WhereClauseOption ,
2544
+ ) -> Option < ( String , bool ) > {
2472
2545
let block_shape = shape. block ( ) . with_max_width ( context. config ) ;
2546
+ // 1 = `,`
2547
+ let clause_shape = block_shape
2548
+ . block_left ( context. config . tab_spaces ( ) ) ?
2549
+ . sub_width ( 1 ) ?;
2550
+
2551
+ let comment_separator = |comment : & str , shape : Shape | {
2552
+ if comment. is_empty ( ) {
2553
+ Cow :: from ( "" )
2554
+ } else {
2555
+ shape. indent . to_string_with_newline ( context. config )
2556
+ }
2557
+ } ;
2473
2558
2474
2559
let ( span_before, span_after) =
2475
2560
missing_span_before_after_where ( span_end_before_where, where_clause) ;
2476
2561
let ( comment_before, comment_after) =
2477
2562
rewrite_comments_before_after_where ( context, span_before, span_after, shape) ?;
2478
2563
2479
- let starting_newline = if where_clause_option. snuggle && comment_before . is_empty ( ) {
2480
- Cow :: from ( " " )
2481
- } else {
2482
- block_shape. indent . to_string_with_newline ( context. config )
2564
+ let starting_newline = match where_clause_option. snuggle {
2565
+ WhereClauseSpace :: Space if comment_before . is_empty ( ) => Cow :: from ( " " ) ,
2566
+ WhereClauseSpace :: None => Cow :: from ( "" ) ,
2567
+ _ => block_shape. indent . to_string_with_newline ( context. config ) ,
2483
2568
} ;
2484
2569
2485
- let clause_shape = block_shape. block_left ( context. config . tab_spaces ( ) ) ?;
2486
- // 1 = `,`
2487
- let clause_shape = clause_shape. sub_width ( 1 ) ?;
2488
- // each clause on one line, trailing comma (except if suppress_comma)
2570
+ let newline_before_where = comment_separator ( & comment_before, shape) ;
2571
+ let newline_after_where = comment_separator ( & comment_after, clause_shape) ;
2572
+ let result = format ! (
2573
+ "{}{}{}where{}{}" ,
2574
+ starting_newline, comment_before, newline_before_where, newline_after_where, comment_after
2575
+ ) ;
2576
+ let allow_single_line = where_clause_option. allow_single_line
2577
+ && comment_before. is_empty ( )
2578
+ && comment_after. is_empty ( ) ;
2579
+
2580
+ Some ( ( result, allow_single_line) )
2581
+ }
2582
+
2583
+ /// Rewrite bounds on a where clause.
2584
+ fn rewrite_bounds_on_where_clause (
2585
+ context : & RewriteContext < ' _ > ,
2586
+ where_clause : & ast:: WhereClause ,
2587
+ shape : Shape ,
2588
+ terminator : & str ,
2589
+ span_end : Option < BytePos > ,
2590
+ where_clause_option : WhereClauseOption ,
2591
+ force_single_line : bool ,
2592
+ ) -> Option < String > {
2489
2593
let span_start = where_clause. predicates [ 0 ] . span ( ) . lo ( ) ;
2490
2594
// If we don't have the start of the next span, then use the end of the
2491
2595
// predicates, but that means we miss comments.
@@ -2499,64 +2603,30 @@ fn rewrite_where_clause_rfc_style(
2499
2603
"," ,
2500
2604
|pred| pred. span ( ) . lo ( ) ,
2501
2605
|pred| pred. span ( ) . hi ( ) ,
2502
- |pred| pred. rewrite ( context, clause_shape ) ,
2606
+ |pred| pred. rewrite ( context, shape ) ,
2503
2607
span_start,
2504
2608
span_end,
2505
2609
false ,
2506
2610
) ;
2507
- let where_single_line = context. config . where_single_line ( ) && len == 1 && !is_args_multi_line;
2508
- let comma_tactic = if where_clause_option. suppress_comma || where_single_line {
2611
+ let comma_tactic = if where_clause_option. suppress_comma || force_single_line {
2509
2612
SeparatorTactic :: Never
2510
2613
} else {
2511
2614
context. config . trailing_comma ( )
2512
2615
} ;
2513
2616
2514
- // shape should be vertical only and only if we have `where_single_line ` option enabled
2617
+ // shape should be vertical only and only if we have `force_single_line ` option enabled
2515
2618
// and the number of items of the where-clause is equal to 1
2516
- let shape_tactic = if where_single_line {
2619
+ let shape_tactic = if force_single_line {
2517
2620
DefinitiveListTactic :: Horizontal
2518
2621
} else {
2519
2622
DefinitiveListTactic :: Vertical
2520
2623
} ;
2521
2624
2522
- let fmt = ListFormatting :: new ( clause_shape , context. config )
2625
+ let fmt = ListFormatting :: new ( shape , context. config )
2523
2626
. tactic ( shape_tactic)
2524
2627
. trailing_separator ( comma_tactic)
2525
2628
. preserve_newline ( true ) ;
2526
- let preds_str = write_list ( & items. collect :: < Vec < _ > > ( ) , & fmt) ?;
2527
-
2528
- let comment_separator = |comment : & str , shape : Shape | {
2529
- if comment. is_empty ( ) {
2530
- Cow :: from ( "" )
2531
- } else {
2532
- shape. indent . to_string_with_newline ( context. config )
2533
- }
2534
- } ;
2535
- let newline_before_where = comment_separator ( & comment_before, shape) ;
2536
- let newline_after_where = comment_separator ( & comment_after, clause_shape) ;
2537
-
2538
- // 6 = `where `
2539
- let clause_sep = if where_clause_option. compress_where
2540
- && comment_before. is_empty ( )
2541
- && comment_after. is_empty ( )
2542
- && !preds_str. contains ( '\n' )
2543
- && 6 + preds_str. len ( ) <= shape. width
2544
- || where_single_line
2545
- {
2546
- Cow :: from ( " " )
2547
- } else {
2548
- clause_shape. indent . to_string_with_newline ( context. config )
2549
- } ;
2550
- Some ( format ! (
2551
- "{}{}{}where{}{}{}{}" ,
2552
- starting_newline,
2553
- comment_before,
2554
- newline_before_where,
2555
- newline_after_where,
2556
- comment_after,
2557
- clause_sep,
2558
- preds_str
2559
- ) )
2629
+ write_list ( & items. collect :: < Vec < _ > > ( ) , & fmt)
2560
2630
}
2561
2631
2562
2632
fn rewrite_where_clause (
@@ -2569,7 +2639,6 @@ fn rewrite_where_clause(
2569
2639
span_end : Option < BytePos > ,
2570
2640
span_end_before_where : BytePos ,
2571
2641
where_clause_option : WhereClauseOption ,
2572
- is_args_multi_line : bool ,
2573
2642
) -> Option < String > {
2574
2643
if where_clause. predicates . is_empty ( ) {
2575
2644
return Some ( String :: new ( ) ) ;
@@ -2584,7 +2653,6 @@ fn rewrite_where_clause(
2584
2653
span_end,
2585
2654
span_end_before_where,
2586
2655
where_clause_option,
2587
- is_args_multi_line,
2588
2656
) ;
2589
2657
}
2590
2658
@@ -2742,7 +2810,6 @@ fn format_generics(
2742
2810
Some ( span. hi ( ) ) ,
2743
2811
span_end_before_where,
2744
2812
option,
2745
- false ,
2746
2813
) ?;
2747
2814
result. push_str ( & where_clause_str) ;
2748
2815
(
0 commit comments