Skip to content

Commit 047a520

Browse files
authored
Merge pull request #2528 from topecongiro/rfc/trait-impl-where
Implement RFC style for trait
2 parents f5ebcd9 + 182b46e commit 047a520

File tree

10 files changed

+225
-173
lines changed

10 files changed

+225
-173
lines changed

src/expr.rs

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1698,7 +1698,8 @@ fn rewrite_match_body(
16981698
);
16991699
match (orig_body, next_line_body) {
17001700
(Some(ref orig_str), Some(ref next_line_str))
1701-
if forbid_same_line || prefer_next_line(orig_str, next_line_str) =>
1701+
if forbid_same_line
1702+
|| prefer_next_line(orig_str, next_line_str, RhsTactics::Default) =>
17021703
{
17031704
combine_next_line_body(next_line_str)
17041705
}
@@ -2514,13 +2515,32 @@ fn rewrite_assignment(
25142515
rewrite_assign_rhs(context, lhs_str, rhs, shape)
25152516
}
25162517

2518+
/// Controls where to put the rhs.
2519+
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
2520+
pub enum RhsTactics {
2521+
/// Use heuristics.
2522+
Default,
2523+
/// Put the rhs on the next line if it uses multiple line.
2524+
ForceNextLine,
2525+
}
2526+
25172527
// The left hand side must contain everything up to, and including, the
25182528
// assignment operator.
25192529
pub fn rewrite_assign_rhs<S: Into<String>, R: Rewrite>(
25202530
context: &RewriteContext,
25212531
lhs: S,
25222532
ex: &R,
25232533
shape: Shape,
2534+
) -> Option<String> {
2535+
rewrite_assign_rhs_with(context, lhs, ex, shape, RhsTactics::Default)
2536+
}
2537+
2538+
pub fn rewrite_assign_rhs_with<S: Into<String>, R: Rewrite>(
2539+
context: &RewriteContext,
2540+
lhs: S,
2541+
ex: &R,
2542+
shape: Shape,
2543+
rhs_tactics: RhsTactics,
25242544
) -> Option<String> {
25252545
let lhs = lhs.into();
25262546
let last_line_width = last_line_width(&lhs)
@@ -2536,15 +2556,22 @@ pub fn rewrite_assign_rhs<S: Into<String>, R: Rewrite>(
25362556
offset: shape.offset + last_line_width + 1,
25372557
..shape
25382558
});
2539-
let rhs = choose_rhs(context, ex, orig_shape, ex.rewrite(context, orig_shape))?;
2559+
let rhs = choose_rhs(
2560+
context,
2561+
ex,
2562+
orig_shape,
2563+
ex.rewrite(context, orig_shape),
2564+
rhs_tactics,
2565+
)?;
25402566
Some(lhs + &rhs)
25412567
}
25422568

2543-
pub fn choose_rhs<R: Rewrite>(
2569+
fn choose_rhs<R: Rewrite>(
25442570
context: &RewriteContext,
25452571
expr: &R,
25462572
shape: Shape,
25472573
orig_rhs: Option<String>,
2574+
rhs_tactics: RhsTactics,
25482575
) -> Option<String> {
25492576
match orig_rhs {
25502577
Some(ref new_str) if !new_str.contains('\n') && new_str.len() <= shape.width => {
@@ -2566,7 +2593,9 @@ pub fn choose_rhs<R: Rewrite>(
25662593
{
25672594
Some(format!(" {}", orig_rhs))
25682595
}
2569-
(Some(ref orig_rhs), Some(ref new_rhs)) if prefer_next_line(orig_rhs, new_rhs) => {
2596+
(Some(ref orig_rhs), Some(ref new_rhs))
2597+
if prefer_next_line(orig_rhs, new_rhs, rhs_tactics) =>
2598+
{
25702599
Some(format!("{}{}", new_indent_str, new_rhs))
25712600
}
25722601
(None, Some(ref new_rhs)) => Some(format!("{}{}", new_indent_str, new_rhs)),
@@ -2577,8 +2606,9 @@ pub fn choose_rhs<R: Rewrite>(
25772606
}
25782607
}
25792608

2580-
fn prefer_next_line(orig_rhs: &str, next_line_rhs: &str) -> bool {
2581-
!next_line_rhs.contains('\n') || count_newlines(orig_rhs) > count_newlines(next_line_rhs) + 1
2609+
fn prefer_next_line(orig_rhs: &str, next_line_rhs: &str, rhs_tactics: RhsTactics) -> bool {
2610+
rhs_tactics == RhsTactics::ForceNextLine || !next_line_rhs.contains('\n')
2611+
|| count_newlines(orig_rhs) > count_newlines(next_line_rhs) + 1
25822612
}
25832613

25842614
fn rewrite_expr_addrof(

src/items.rs

Lines changed: 54 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,14 @@ use codemap::{LineRangeUtils, SpanUtils};
2323
use comment::{combine_strs_with_missing_comments, contains_comment, recover_comment_removed,
2424
recover_missing_comment_in_span, rewrite_missing_comment, FindUncommented};
2525
use config::{BraceStyle, Config, Density, IndentStyle};
26-
use expr::{format_expr, is_empty_block, is_simple_block_stmt, rewrite_assign_rhs, ExprType};
26+
use expr::{format_expr, is_empty_block, is_simple_block_stmt, rewrite_assign_rhs,
27+
rewrite_assign_rhs_with, ExprType, RhsTactics};
2728
use lists::{definitive_tactic, itemize_list, write_list, ListFormatting, ListItem, Separator};
2829
use rewrite::{Rewrite, RewriteContext};
2930
use overflow;
3031
use shape::{Indent, Shape};
3132
use spanned::Spanned;
32-
use types::join_bounds;
33+
use types::TraitTyParamBounds;
3334
use utils::{colon_spaces, contains_skip, first_line_width, format_abi, format_constness,
3435
format_defaultness, format_mutability, format_unsafety, format_visibility,
3536
is_attributes_extendable, last_line_contains_single_line_comment,
@@ -919,60 +920,55 @@ pub fn format_trait(context: &RewriteContext, item: &ast::Item, offset: Indent)
919920
return None;
920921
}
921922
}
922-
let trait_bound_str = rewrite_trait_bounds(
923-
context,
924-
type_param_bounds,
925-
Shape::indented(offset, context.config),
926-
)?;
927-
// If the trait, generics, and trait bound cannot fit on the same line,
928-
// put the trait bounds on an indented new line
929-
if offset.width() + last_line_width(&result) + trait_bound_str.len()
930-
> context.config.comment_width()
931-
{
932-
let trait_indent = offset.block_only().block_indent(context.config);
933-
result.push_str(&trait_indent.to_string_with_newline(context.config));
923+
if !type_param_bounds.is_empty() {
924+
result = rewrite_assign_rhs_with(
925+
context,
926+
result + ":",
927+
&TraitTyParamBounds::new(type_param_bounds),
928+
shape,
929+
RhsTactics::ForceNextLine,
930+
)?;
934931
}
935-
result.push_str(&trait_bound_str);
936932

937-
let where_density =
938-
if context.config.indent_style() == IndentStyle::Block && result.is_empty() {
933+
// Rewrite where clause.
934+
if !generics.where_clause.predicates.is_empty() {
935+
let where_density = if context.config.indent_style() == IndentStyle::Block {
939936
Density::Compressed
940937
} else {
941938
Density::Tall
942939
};
943940

944-
let where_budget = context.budget(last_line_width(&result));
945-
let pos_before_where = if type_param_bounds.is_empty() {
946-
generics.where_clause.span.lo()
941+
let where_budget = context.budget(last_line_width(&result));
942+
let pos_before_where = if type_param_bounds.is_empty() {
943+
generics.where_clause.span.lo()
944+
} else {
945+
type_param_bounds[type_param_bounds.len() - 1].span().hi()
946+
};
947+
let option = WhereClauseOption::snuggled(&generics_str);
948+
let where_clause_str = rewrite_where_clause(
949+
context,
950+
&generics.where_clause,
951+
context.config.brace_style(),
952+
Shape::legacy(where_budget, offset.block_only()),
953+
where_density,
954+
"{",
955+
None,
956+
pos_before_where,
957+
option,
958+
false,
959+
)?;
960+
// If the where clause cannot fit on the same line,
961+
// put the where clause on a new line
962+
if !where_clause_str.contains('\n')
963+
&& last_line_width(&result) + where_clause_str.len() + offset.width()
964+
> context.config.comment_width()
965+
{
966+
let width = offset.block_indent + context.config.tab_spaces() - 1;
967+
let where_indent = Indent::new(0, width);
968+
result.push_str(&where_indent.to_string_with_newline(context.config));
969+
}
970+
result.push_str(&where_clause_str);
947971
} else {
948-
type_param_bounds[type_param_bounds.len() - 1].span().hi()
949-
};
950-
let option = WhereClauseOption::snuggled(&generics_str);
951-
let where_clause_str = rewrite_where_clause(
952-
context,
953-
&generics.where_clause,
954-
context.config.brace_style(),
955-
Shape::legacy(where_budget, offset.block_only()),
956-
where_density,
957-
"{",
958-
None,
959-
pos_before_where,
960-
option,
961-
false,
962-
)?;
963-
// If the where clause cannot fit on the same line,
964-
// put the where clause on a new line
965-
if !where_clause_str.contains('\n')
966-
&& last_line_width(&result) + where_clause_str.len() + offset.width()
967-
> context.config.comment_width()
968-
{
969-
let width = offset.block_indent + context.config.tab_spaces() - 1;
970-
let where_indent = Indent::new(0, width);
971-
result.push_str(&where_indent.to_string_with_newline(context.config));
972-
}
973-
result.push_str(&where_clause_str);
974-
975-
if generics.where_clause.predicates.is_empty() {
976972
let item_snippet = context.snippet(item.span);
977973
if let Some(lo) = item_snippet.chars().position(|c| c == '/') {
978974
// 1 = `{`
@@ -995,16 +991,18 @@ pub fn format_trait(context: &RewriteContext, item: &ast::Item, offset: Indent)
995991
}
996992

997993
match context.config.brace_style() {
998-
_ if last_line_contains_single_line_comment(&result) => {
994+
_ if last_line_contains_single_line_comment(&result)
995+
|| last_line_width(&result) + 2 > context.budget(offset.width()) =>
996+
{
999997
result.push_str(&offset.to_string_with_newline(context.config));
1000998
}
1001999
BraceStyle::AlwaysNextLine => {
10021000
result.push_str(&offset.to_string_with_newline(context.config));
10031001
}
10041002
BraceStyle::PreferSameLine => result.push(' '),
10051003
BraceStyle::SameLineWhere => {
1006-
if !where_clause_str.is_empty()
1007-
&& (!trait_items.is_empty() || result.contains('\n'))
1004+
if result.contains('\n')
1005+
|| (!generics.where_clause.predicates.is_empty() && !trait_items.is_empty())
10081006
{
10091007
result.push_str(&offset.to_string_with_newline(context.config));
10101008
} else {
@@ -1585,16 +1583,12 @@ pub fn rewrite_associated_type(
15851583
let prefix = format!("type {}", ident);
15861584

15871585
let type_bounds_str = if let Some(bounds) = ty_param_bounds_opt {
1588-
// 2 = ": ".len()
1589-
let shape = Shape::indented(indent, context.config).offset_left(prefix.len() + 2)?;
1590-
let bound_str = bounds
1591-
.iter()
1592-
.map(|ty_bound| ty_bound.rewrite(context, shape))
1593-
.collect::<Option<Vec<_>>>()?;
1594-
if !bounds.is_empty() {
1595-
format!(": {}", join_bounds(context, shape, &bound_str))
1596-
} else {
1586+
if bounds.is_empty() {
15971587
String::new()
1588+
} else {
1589+
// 2 = ": ".len()
1590+
let shape = Shape::indented(indent, context.config).offset_left(prefix.len() + 2)?;
1591+
bounds.rewrite(context, shape).map(|s| format!(": {}", s))?
15981592
}
15991593
} else {
16001594
String::new()
@@ -2329,21 +2323,6 @@ pub fn generics_shape_from_config(config: &Config, shape: Shape, offset: usize)
23292323
}
23302324
}
23312325

2332-
fn rewrite_trait_bounds(
2333-
context: &RewriteContext,
2334-
bounds: &[ast::TyParamBound],
2335-
shape: Shape,
2336-
) -> Option<String> {
2337-
if bounds.is_empty() {
2338-
return Some(String::new());
2339-
}
2340-
let bound_str = bounds
2341-
.iter()
2342-
.map(|ty_bound| ty_bound.rewrite(context, shape))
2343-
.collect::<Option<Vec<_>>>()?;
2344-
Some(format!(": {}", join_bounds(context, shape, &bound_str)))
2345-
}
2346-
23472326
fn rewrite_where_clause_rfc_style(
23482327
context: &RewriteContext,
23492328
where_clause: &ast::WhereClause,

0 commit comments

Comments
 (0)