@@ -15,9 +15,10 @@ use codemap::SpanUtils;
15
15
use utils:: { format_mutability, format_visibility, contains_skip, end_typaram, wrap_str,
16
16
last_line_width, format_unsafety, trim_newlines, stmt_expr, semicolon_for_expr,
17
17
trimmed_last_line_width, colon_spaces, mk_sp} ;
18
- use lists:: { write_list, itemize_list, ListItem , ListFormatting , SeparatorTactic , list_helper ,
18
+ use lists:: { write_list, itemize_list, ListItem , ListFormatting , SeparatorTactic ,
19
19
DefinitiveListTactic , ListTactic , definitive_tactic} ;
20
- use expr:: { format_expr, is_empty_block, is_simple_block_stmt, rewrite_assign_rhs, ExprType } ;
20
+ use expr:: { format_expr, is_empty_block, is_simple_block_stmt, rewrite_assign_rhs,
21
+ rewrite_call_inner, ExprType } ;
21
22
use comment:: { FindUncommented , contains_comment, rewrite_comment, recover_comment_removed} ;
22
23
use visitor:: FmtVisitor ;
23
24
use rewrite:: { Rewrite , RewriteContext } ;
@@ -392,7 +393,8 @@ impl<'a> FmtVisitor<'a> {
392
393
generics : & ast:: Generics ,
393
394
span : Span ,
394
395
) {
395
- self . buffer . push_str ( & format_header ( "enum " , ident, vis) ) ;
396
+ let enum_header = format_header ( "enum " , ident, vis) ;
397
+ self . buffer . push_str ( & enum_header) ;
396
398
397
399
let enum_snippet = self . snippet ( span) ;
398
400
let brace_pos = enum_snippet. find_uncommented ( "{" ) . unwrap ( ) ;
@@ -406,6 +408,7 @@ impl<'a> FmtVisitor<'a> {
406
408
enum_def. variants . is_empty ( ) ,
407
409
self . block_indent ,
408
410
mk_sp ( span. lo , body_start) ,
411
+ last_line_width ( & enum_header) ,
409
412
) . unwrap ( ) ;
410
413
self . buffer . push_str ( & generics_str) ;
411
414
@@ -1071,19 +1074,38 @@ fn format_struct_struct(
1071
1074
fields. is_empty( ) ,
1072
1075
offset,
1073
1076
mk_sp( span. lo, body_lo) ,
1077
+ last_line_width( & result) ,
1074
1078
) )
1075
1079
}
1076
1080
None => {
1077
- if context. config . item_brace_style ( ) == BraceStyle :: AlwaysNextLine &&
1078
- !fields. is_empty ( )
1081
+ // 3 = ` {}`, 2 = ` {`.
1082
+ let overhead = if fields. is_empty ( ) { 3 } else { 2 } ;
1083
+ if ( context. config . item_brace_style ( ) == BraceStyle :: AlwaysNextLine &&
1084
+ !fields. is_empty ( ) ) ||
1085
+ context
1086
+ . config
1087
+ . max_width ( )
1088
+ . checked_sub ( result. len ( ) )
1089
+ . unwrap_or ( 0 ) < overhead
1079
1090
{
1080
1091
format ! ( "\n {}{{" , offset. block_only( ) . to_string( context. config) )
1081
1092
} else {
1082
1093
" {" . to_owned ( )
1083
1094
}
1084
1095
}
1085
1096
} ;
1086
- result. push_str ( & generics_str) ;
1097
+ // 1 = `}`
1098
+ let overhead = if fields. is_empty ( ) { 1 } else { 0 } ;
1099
+ let max_len = context. config . max_width ( ) - offset. width ( ) ;
1100
+ if !generics_str. contains ( '\n' ) && result. len ( ) + generics_str. len ( ) + overhead > max_len {
1101
+ result. push ( '\n' ) ;
1102
+ result. push_str ( & offset
1103
+ . block_indent ( context. config )
1104
+ . to_string ( context. config ) ) ;
1105
+ result. push_str ( & generics_str. trim_left ( ) ) ;
1106
+ } else {
1107
+ result. push_str ( & generics_str) ;
1108
+ }
1087
1109
1088
1110
if fields. is_empty ( ) {
1089
1111
let snippet = context. snippet ( mk_sp ( body_lo, span. hi - BytePos ( 1 ) ) ) ;
@@ -1147,17 +1169,13 @@ fn format_tuple_struct(
1147
1169
1148
1170
let where_clause_str = match generics {
1149
1171
Some ( generics) => {
1150
- let shape = Shape :: indented ( offset + last_line_width ( & header_str) , context. config ) ;
1172
+ let budget = context. budget ( last_line_width ( & header_str) ) ;
1173
+ let shape = Shape :: legacy ( budget, offset) ;
1151
1174
let g_span = mk_sp ( span. lo , body_lo) ;
1152
1175
let generics_str = try_opt ! ( rewrite_generics( context, generics, shape, g_span) ) ;
1153
1176
result. push_str ( & generics_str) ;
1154
1177
1155
- let where_budget = try_opt ! (
1156
- context
1157
- . config
1158
- . max_width( )
1159
- . checked_sub( last_line_width( & result) )
1160
- ) ;
1178
+ let where_budget = context. budget ( last_line_width ( & result) ) ;
1161
1179
try_opt ! ( rewrite_where_clause(
1162
1180
context,
1163
1181
& generics. where_clause,
@@ -1174,6 +1192,18 @@ fn format_tuple_struct(
1174
1192
} ;
1175
1193
1176
1194
if fields. is_empty ( ) {
1195
+ // 3 = `();`
1196
+ let used_width = if result. contains ( '\n' ) {
1197
+ last_line_width ( & result) + 3
1198
+ } else {
1199
+ offset. width ( ) + result. len ( ) + 3
1200
+ } ;
1201
+ if used_width > context. config . max_width ( ) {
1202
+ result. push ( '\n' ) ;
1203
+ result. push_str ( & offset
1204
+ . block_indent ( context. config )
1205
+ . to_string ( context. config ) )
1206
+ }
1177
1207
result. push ( '(' ) ;
1178
1208
let snippet = context. snippet ( mk_sp ( body_lo, context. codemap . span_before ( span, ")" ) ) ) ;
1179
1209
if snippet. is_empty ( ) {
@@ -1187,82 +1217,19 @@ fn format_tuple_struct(
1187
1217
}
1188
1218
result. push ( ')' ) ;
1189
1219
} else {
1190
- let ( tactic, item_indent) = match context. config . fn_args_layout ( ) {
1191
- IndentStyle :: Visual => {
1192
- // 1 = `(`
1193
- (
1194
- ListTactic :: HorizontalVertical ,
1195
- offset. block_only ( ) + result. len ( ) + 1 ,
1196
- )
1197
- }
1198
- IndentStyle :: Block => {
1199
- (
1200
- ListTactic :: HorizontalVertical ,
1201
- offset. block_only ( ) . block_indent ( & context. config ) ,
1202
- )
1203
- }
1204
- } ;
1205
1220
// 3 = `();`
1206
- let item_budget = try_opt ! (
1207
- context
1208
- . config
1209
- . max_width( )
1210
- . checked_sub( item_indent. width( ) + 3 )
1211
- ) ;
1212
-
1213
- let items = itemize_list (
1214
- context. codemap ,
1215
- fields. iter ( ) ,
1216
- ")" ,
1217
- |field| {
1218
- // Include attributes and doc comments, if present
1219
- if !field. attrs . is_empty ( ) {
1220
- field. attrs [ 0 ] . span . lo
1221
- } else {
1222
- field. span . lo
1223
- }
1224
- } ,
1225
- |field| field. ty . span . hi ,
1226
- |field| {
1227
- rewrite_struct_field ( context, field, Shape :: legacy ( item_budget, item_indent) , 0 )
1228
- } ,
1229
- context. codemap . span_after ( span, "(" ) ,
1230
- span. hi ,
1231
- ) ;
1232
- let body_budget = try_opt ! (
1233
- context
1234
- . config
1235
- . max_width( )
1236
- . checked_sub( offset. block_only( ) . width( ) + result. len( ) + 3 )
1221
+ let body = try_opt ! (
1222
+ rewrite_call_inner(
1223
+ context,
1224
+ "" ,
1225
+ & fields. iter( ) . map( |field| field) . collect:: <Vec <_>>( ) [ ..] ,
1226
+ span,
1227
+ Shape :: legacy( context. budget( last_line_width( & result) + 3 ) , offset) ,
1228
+ context. config. fn_call_width( ) ,
1229
+ false ,
1230
+ ) . ok( )
1237
1231
) ;
1238
- let body = try_opt ! ( list_helper(
1239
- items,
1240
- // TODO budget is wrong in block case
1241
- Shape :: legacy( body_budget, item_indent) ,
1242
- context. config,
1243
- tactic,
1244
- ) ) ;
1245
-
1246
- if context. config . fn_args_layout ( ) == IndentStyle :: Visual || !body. contains ( '\n' ) {
1247
- result. push ( '(' ) ;
1248
- if context. config . spaces_within_parens ( ) && body. len ( ) > 0 {
1249
- result. push ( ' ' ) ;
1250
- }
1251
-
1252
- result. push_str ( & body) ;
1253
-
1254
- if context. config . spaces_within_parens ( ) && body. len ( ) > 0 {
1255
- result. push ( ' ' ) ;
1256
- }
1257
- result. push ( ')' ) ;
1258
- } else {
1259
- result. push_str ( "(\n " ) ;
1260
- result. push_str ( & item_indent. to_string ( & context. config ) ) ;
1261
- result. push_str ( & body) ;
1262
- result. push ( '\n' ) ;
1263
- result. push_str ( & offset. block_only ( ) . to_string ( & context. config ) ) ;
1264
- result. push ( ')' ) ;
1265
- }
1232
+ result. push_str ( & body) ;
1266
1233
}
1267
1234
1268
1235
if !where_clause_str. is_empty ( ) && !where_clause_str. contains ( '\n' ) &&
@@ -1452,6 +1419,11 @@ fn rewrite_struct_field_type(
1452
1419
. map ( |ty| format ! ( "{}{}" , spacing, ty) )
1453
1420
}
1454
1421
1422
+ impl Rewrite for ast:: StructField {
1423
+ fn rewrite ( & self , context : & RewriteContext , shape : Shape ) -> Option < String > {
1424
+ rewrite_struct_field ( context, self , shape, 0 )
1425
+ }
1426
+ }
1455
1427
1456
1428
pub fn rewrite_struct_field (
1457
1429
context : & RewriteContext ,
@@ -2384,7 +2356,7 @@ fn rewrite_generics(
2384
2356
span : Span ,
2385
2357
) -> Option < String > {
2386
2358
let g_shape = try_opt ! ( generics_shape_from_config( context. config, shape, 0 ) ) ;
2387
- let one_line_width = try_opt ! ( shape. width. checked_sub( 2 ) ) ;
2359
+ let one_line_width = shape. width . checked_sub ( 2 ) . unwrap_or ( 0 ) ;
2388
2360
rewrite_generics_inner ( context, generics, g_shape, one_line_width, span) . or_else ( || {
2389
2361
rewrite_generics_inner ( context, generics, g_shape, 0 , span)
2390
2362
} )
@@ -2459,16 +2431,19 @@ where
2459
2431
{
2460
2432
let item_vec = items. collect :: < Vec < _ > > ( ) ;
2461
2433
2434
+ let tactic = definitive_tactic ( & item_vec, ListTactic :: HorizontalVertical , one_line_budget) ;
2435
+ let ends_with_newline = context. config . generics_indent ( ) == IndentStyle :: Block &&
2436
+ tactic == DefinitiveListTactic :: Vertical ;
2462
2437
let fmt = ListFormatting {
2463
- tactic : definitive_tactic ( & item_vec , ListTactic :: HorizontalVertical , one_line_budget ) ,
2438
+ tactic : tactic ,
2464
2439
separator : "," ,
2465
2440
trailing_separator : if context. config . generics_indent ( ) == IndentStyle :: Visual {
2466
2441
SeparatorTactic :: Never
2467
2442
} else {
2468
2443
context. config . trailing_comma ( )
2469
2444
} ,
2470
2445
shape : shape,
2471
- ends_with_newline : false ,
2446
+ ends_with_newline : ends_with_newline ,
2472
2447
config : context. config ,
2473
2448
} ;
2474
2449
@@ -2697,8 +2672,9 @@ fn format_generics(
2697
2672
force_same_line_brace : bool ,
2698
2673
offset : Indent ,
2699
2674
span : Span ,
2675
+ used_width : usize ,
2700
2676
) -> Option < String > {
2701
- let shape = Shape :: indented ( offset, context . config ) ;
2677
+ let shape = Shape :: legacy ( context . budget ( used_width + offset. width ( ) ) , offset ) ;
2702
2678
let mut result = try_opt ! ( rewrite_generics( context, generics, shape, span) ) ;
2703
2679
2704
2680
if !generics. where_clause . predicates . is_empty ( ) || result. contains ( '\n' ) {
0 commit comments