Skip to content

Commit 6b00353

Browse files
authored
Merge pull request #1746 from topecongiro/struct-tuple
RFC: Use block indent style for struct tuple
2 parents 818ff7a + 6a7f866 commit 6b00353

14 files changed

+195
-175
lines changed

src/expr.rs

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,12 @@ use {Indent, Shape, Spanned};
1616
use codemap::SpanUtils;
1717
use rewrite::{Rewrite, RewriteContext};
1818
use lists::{write_list, itemize_list, ListFormatting, SeparatorTactic, ListTactic,
19-
DefinitiveListTactic, definitive_tactic, ListItem, format_item_list, struct_lit_shape,
19+
DefinitiveListTactic, definitive_tactic, ListItem, struct_lit_shape,
2020
struct_lit_tactic, shape_for_tactic, struct_lit_formatting};
2121
use string::{StringFormat, rewrite_string};
2222
use utils::{extra_offset, last_line_width, wrap_str, binary_search, first_line_width,
2323
semicolon_for_stmt, trimmed_last_line_width, left_most_sub_expr, stmt_expr,
24-
colon_spaces, contains_skip, mk_sp, last_line_extendable};
24+
colon_spaces, contains_skip, mk_sp, last_line_extendable, paren_overhead};
2525
use visitor::FmtVisitor;
2626
use config::{Config, IndentStyle, MultilineStyle, ControlBraceStyle, Style};
2727
use comment::{FindUncommented, rewrite_comment, contains_comment, recover_comment_removed};
@@ -2217,7 +2217,7 @@ where
22172217
context.config.trailing_comma()
22182218
},
22192219
shape: shape,
2220-
ends_with_newline: false,
2220+
ends_with_newline: context.use_block_indent() && tactic == DefinitiveListTactic::Vertical,
22212221
config: context.config,
22222222
};
22232223

@@ -2436,14 +2436,6 @@ pub fn can_be_overflowed_expr(context: &RewriteContext, expr: &ast::Expr, args_l
24362436
}
24372437
}
24382438

2439-
fn paren_overhead(context: &RewriteContext) -> usize {
2440-
if context.config.spaces_within_parens() {
2441-
4
2442-
} else {
2443-
2
2444-
}
2445-
}
2446-
24472439
pub fn wrap_args_with_parens(
24482440
context: &RewriteContext,
24492441
args_str: &str,
@@ -2813,7 +2805,21 @@ where
28132805
list_lo,
28142806
span.hi - BytePos(1),
28152807
);
2816-
let list_str = try_opt!(format_item_list(items, nested_shape, context.config));
2808+
let item_vec: Vec<_> = items.collect();
2809+
let tactic = definitive_tactic(
2810+
&item_vec,
2811+
ListTactic::HorizontalVertical,
2812+
nested_shape.width,
2813+
);
2814+
let fmt = ListFormatting {
2815+
tactic: tactic,
2816+
separator: ",",
2817+
trailing_separator: SeparatorTactic::Never,
2818+
shape: shape,
2819+
ends_with_newline: false,
2820+
config: context.config,
2821+
};
2822+
let list_str = try_opt!(write_list(&item_vec, &fmt));
28172823

28182824
if context.config.spaces_within_parens() && list_str.len() > 0 {
28192825
Some(format!("( {} )", list_str))
@@ -3023,3 +3029,13 @@ impl<'a> ToExpr for TuplePatField<'a> {
30233029
can_be_overflowed_pat(context, self, len)
30243030
}
30253031
}
3032+
3033+
impl<'a> ToExpr for ast::StructField {
3034+
fn to_expr(&self) -> Option<&ast::Expr> {
3035+
None
3036+
}
3037+
3038+
fn can_be_overflowed(&self, _: &RewriteContext, _: usize) -> bool {
3039+
false
3040+
}
3041+
}

src/file_lines.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,9 @@ impl FileLines {
167167
}
168168

169169
/// FileLines files iterator.
170-
pub struct Files<'a>(Option<::std::collections::hash_map::Keys<'a, String, Vec<Range>>>);
170+
pub struct Files<'a>(
171+
Option<::std::collections::hash_map::Keys<'a, String, Vec<Range>>>,
172+
);
171173

172174
impl<'a> iter::Iterator for Files<'a> {
173175
type Item = &'a String;

src/items.rs

Lines changed: 67 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,10 @@ use codemap::SpanUtils;
1515
use utils::{format_mutability, format_visibility, contains_skip, end_typaram, wrap_str,
1616
last_line_width, format_unsafety, trim_newlines, stmt_expr, semicolon_for_expr,
1717
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,
1919
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};
2122
use comment::{FindUncommented, contains_comment, rewrite_comment, recover_comment_removed};
2223
use visitor::FmtVisitor;
2324
use rewrite::{Rewrite, RewriteContext};
@@ -392,7 +393,8 @@ impl<'a> FmtVisitor<'a> {
392393
generics: &ast::Generics,
393394
span: Span,
394395
) {
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);
396398

397399
let enum_snippet = self.snippet(span);
398400
let brace_pos = enum_snippet.find_uncommented("{").unwrap();
@@ -406,6 +408,7 @@ impl<'a> FmtVisitor<'a> {
406408
enum_def.variants.is_empty(),
407409
self.block_indent,
408410
mk_sp(span.lo, body_start),
411+
last_line_width(&enum_header),
409412
).unwrap();
410413
self.buffer.push_str(&generics_str);
411414

@@ -1071,19 +1074,38 @@ fn format_struct_struct(
10711074
fields.is_empty(),
10721075
offset,
10731076
mk_sp(span.lo, body_lo),
1077+
last_line_width(&result),
10741078
))
10751079
}
10761080
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
10791090
{
10801091
format!("\n{}{{", offset.block_only().to_string(context.config))
10811092
} else {
10821093
" {".to_owned()
10831094
}
10841095
}
10851096
};
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+
}
10871109

10881110
if fields.is_empty() {
10891111
let snippet = context.snippet(mk_sp(body_lo, span.hi - BytePos(1)));
@@ -1147,17 +1169,13 @@ fn format_tuple_struct(
11471169

11481170
let where_clause_str = match generics {
11491171
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);
11511174
let g_span = mk_sp(span.lo, body_lo);
11521175
let generics_str = try_opt!(rewrite_generics(context, generics, shape, g_span));
11531176
result.push_str(&generics_str);
11541177

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));
11611179
try_opt!(rewrite_where_clause(
11621180
context,
11631181
&generics.where_clause,
@@ -1174,6 +1192,18 @@ fn format_tuple_struct(
11741192
};
11751193

11761194
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+
}
11771207
result.push('(');
11781208
let snippet = context.snippet(mk_sp(body_lo, context.codemap.span_before(span, ")")));
11791209
if snippet.is_empty() {
@@ -1187,82 +1217,19 @@ fn format_tuple_struct(
11871217
}
11881218
result.push(')');
11891219
} 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-
};
12051220
// 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()
12371231
);
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);
12661233
}
12671234

12681235
if !where_clause_str.is_empty() && !where_clause_str.contains('\n') &&
@@ -1452,6 +1419,11 @@ fn rewrite_struct_field_type(
14521419
.map(|ty| format!("{}{}", spacing, ty))
14531420
}
14541421

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+
}
14551427

14561428
pub fn rewrite_struct_field(
14571429
context: &RewriteContext,
@@ -2384,7 +2356,7 @@ fn rewrite_generics(
23842356
span: Span,
23852357
) -> Option<String> {
23862358
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);
23882360
rewrite_generics_inner(context, generics, g_shape, one_line_width, span).or_else(|| {
23892361
rewrite_generics_inner(context, generics, g_shape, 0, span)
23902362
})
@@ -2459,16 +2431,19 @@ where
24592431
{
24602432
let item_vec = items.collect::<Vec<_>>();
24612433

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;
24622437
let fmt = ListFormatting {
2463-
tactic: definitive_tactic(&item_vec, ListTactic::HorizontalVertical, one_line_budget),
2438+
tactic: tactic,
24642439
separator: ",",
24652440
trailing_separator: if context.config.generics_indent() == IndentStyle::Visual {
24662441
SeparatorTactic::Never
24672442
} else {
24682443
context.config.trailing_comma()
24692444
},
24702445
shape: shape,
2471-
ends_with_newline: false,
2446+
ends_with_newline: ends_with_newline,
24722447
config: context.config,
24732448
};
24742449

@@ -2697,8 +2672,9 @@ fn format_generics(
26972672
force_same_line_brace: bool,
26982673
offset: Indent,
26992674
span: Span,
2675+
used_width: usize,
27002676
) -> Option<String> {
2701-
let shape = Shape::indented(offset, context.config);
2677+
let shape = Shape::legacy(context.budget(used_width + offset.width()), offset);
27022678
let mut result = try_opt!(rewrite_generics(context, generics, shape, span));
27032679

27042680
if !generics.where_clause.predicates.is_empty() || result.contains('\n') {

0 commit comments

Comments
 (0)