Use rewrite_assign_rhs for rewriting bounds
This commit is contained in:
parent
8f7a90fbef
commit
f56039c7e5
59
src/items.rs
59
src/items.rs
@ -23,13 +23,14 @@
|
||||
use comment::{combine_strs_with_missing_comments, contains_comment, recover_comment_removed,
|
||||
recover_missing_comment_in_span, rewrite_missing_comment, FindUncommented};
|
||||
use config::{BraceStyle, Config, Density, IndentStyle};
|
||||
use expr::{format_expr, is_empty_block, is_simple_block_stmt, rewrite_assign_rhs, ExprType};
|
||||
use expr::{format_expr, is_empty_block, is_simple_block_stmt, rewrite_assign_rhs,
|
||||
rewrite_assign_rhs_with, ExprType, RhsTactics};
|
||||
use lists::{definitive_tactic, itemize_list, write_list, ListFormatting, ListItem, Separator};
|
||||
use rewrite::{Rewrite, RewriteContext};
|
||||
use overflow;
|
||||
use shape::{Indent, Shape};
|
||||
use spanned::Spanned;
|
||||
use types::join_bounds;
|
||||
use types::TraitTyParamBounds;
|
||||
use utils::{colon_spaces, contains_skip, first_line_width, format_abi, format_constness,
|
||||
format_defaultness, format_mutability, format_unsafety, format_visibility,
|
||||
is_attributes_extendable, last_line_contains_single_line_comment,
|
||||
@ -919,20 +920,19 @@ pub fn format_trait(context: &RewriteContext, item: &ast::Item, offset: Indent)
|
||||
return None;
|
||||
}
|
||||
}
|
||||
let trait_bound_str = rewrite_trait_bounds(
|
||||
context,
|
||||
type_param_bounds,
|
||||
Shape::indented(offset, context.config),
|
||||
)?;
|
||||
// If the trait, generics, and trait bound cannot fit on the same line,
|
||||
// put the trait bounds on an indented new line
|
||||
if offset.width() + last_line_width(&result) + trait_bound_str.len()
|
||||
> context.config.comment_width()
|
||||
{
|
||||
let trait_indent = offset.block_only().block_indent(context.config);
|
||||
result.push_str(&trait_indent.to_string_with_newline(context.config));
|
||||
if !type_param_bounds.is_empty() {
|
||||
let shape = Shape {
|
||||
indent: shape.indent.block_unindent(context.config),
|
||||
..shape
|
||||
};
|
||||
result = rewrite_assign_rhs_with(
|
||||
context,
|
||||
result + ":",
|
||||
&TraitTyParamBounds::new(type_param_bounds),
|
||||
shape,
|
||||
RhsTactics::ForceNextLine,
|
||||
)?;
|
||||
}
|
||||
result.push_str(&trait_bound_str);
|
||||
|
||||
let where_density =
|
||||
if context.config.indent_style() == IndentStyle::Block && result.is_empty() {
|
||||
@ -1585,16 +1585,12 @@ pub fn rewrite_associated_type(
|
||||
let prefix = format!("type {}", ident);
|
||||
|
||||
let type_bounds_str = if let Some(bounds) = ty_param_bounds_opt {
|
||||
// 2 = ": ".len()
|
||||
let shape = Shape::indented(indent, context.config).offset_left(prefix.len() + 2)?;
|
||||
let bound_str = bounds
|
||||
.iter()
|
||||
.map(|ty_bound| ty_bound.rewrite(context, shape))
|
||||
.collect::<Option<Vec<_>>>()?;
|
||||
if !bounds.is_empty() {
|
||||
format!(": {}", join_bounds(context, shape, &bound_str))
|
||||
} else {
|
||||
if bounds.is_empty() {
|
||||
String::new()
|
||||
} else {
|
||||
// 2 = ": ".len()
|
||||
let shape = Shape::indented(indent, context.config).offset_left(prefix.len() + 2)?;
|
||||
bounds.rewrite(context, shape).map(|s| format!(": {}", s))?
|
||||
}
|
||||
} else {
|
||||
String::new()
|
||||
@ -2329,21 +2325,6 @@ pub fn generics_shape_from_config(config: &Config, shape: Shape, offset: usize)
|
||||
}
|
||||
}
|
||||
|
||||
fn rewrite_trait_bounds(
|
||||
context: &RewriteContext,
|
||||
bounds: &[ast::TyParamBound],
|
||||
shape: Shape,
|
||||
) -> Option<String> {
|
||||
if bounds.is_empty() {
|
||||
return Some(String::new());
|
||||
}
|
||||
let bound_str = bounds
|
||||
.iter()
|
||||
.map(|ty_bound| ty_bound.rewrite(context, shape))
|
||||
.collect::<Option<Vec<_>>>()?;
|
||||
Some(format!(": {}", join_bounds(context, shape, &bound_str)))
|
||||
}
|
||||
|
||||
fn rewrite_where_clause_rfc_style(
|
||||
context: &RewriteContext,
|
||||
where_clause: &ast::WhereClause,
|
||||
|
126
src/types.rs
126
src/types.rs
@ -18,7 +18,8 @@
|
||||
|
||||
use codemap::SpanUtils;
|
||||
use config::{IndentStyle, TypeDensity};
|
||||
use expr::{rewrite_pair, rewrite_tuple, rewrite_unary_prefix, PairParts, ToExpr};
|
||||
use expr::{rewrite_assign_rhs, rewrite_pair, rewrite_tuple, rewrite_unary_prefix,
|
||||
PairParts, ToExpr};
|
||||
use lists::{definitive_tactic, itemize_list, write_list, ListFormatting, Separator};
|
||||
use macros::{rewrite_macro, MacroPosition};
|
||||
use overflow;
|
||||
@ -431,64 +432,35 @@ fn rewrite(&self, context: &RewriteContext, shape: Shape) -> Option<String> {
|
||||
..
|
||||
}) => {
|
||||
let type_str = bounded_ty.rewrite(context, shape)?;
|
||||
|
||||
let colon = type_bound_colon(context);
|
||||
|
||||
if let Some(lifetime_str) =
|
||||
let colon = type_bound_colon(context).trim_right();
|
||||
let lhs = if let Some(lifetime_str) =
|
||||
rewrite_lifetime_param(context, shape, bound_generic_params)
|
||||
{
|
||||
// 6 = "for<> ".len()
|
||||
let used_width = lifetime_str.len() + type_str.len() + colon.len() + 6;
|
||||
let ty_shape = shape.offset_left(used_width)?;
|
||||
let bounds = bounds
|
||||
.iter()
|
||||
.map(|ty_bound| ty_bound.rewrite(context, ty_shape))
|
||||
.collect::<Option<Vec<_>>>()?;
|
||||
let bounds_str = join_bounds(context, ty_shape, &bounds);
|
||||
|
||||
if context.config.spaces_within_parens_and_brackets()
|
||||
&& !lifetime_str.is_empty()
|
||||
{
|
||||
format!(
|
||||
"for< {} > {}{}{}",
|
||||
lifetime_str, type_str, colon, bounds_str
|
||||
)
|
||||
format!("for< {} > {}{}", lifetime_str, type_str, colon)
|
||||
} else {
|
||||
format!("for<{}> {}{}{}", lifetime_str, type_str, colon, bounds_str)
|
||||
format!("for<{}> {}{}", lifetime_str, type_str, colon)
|
||||
}
|
||||
} else {
|
||||
let used_width = type_str.len() + colon.len();
|
||||
let ty_shape = match context.config.indent_style() {
|
||||
IndentStyle::Visual => shape.block_left(used_width)?,
|
||||
IndentStyle::Block => shape,
|
||||
};
|
||||
let bounds = bounds
|
||||
.iter()
|
||||
.map(|ty_bound| ty_bound.rewrite(context, ty_shape))
|
||||
.collect::<Option<Vec<_>>>()?;
|
||||
let overhead = type_str.len() + colon.len();
|
||||
let bounds_str = join_bounds(context, ty_shape.sub_width(overhead)?, &bounds);
|
||||
format!("{}{}", type_str, colon)
|
||||
};
|
||||
|
||||
format!("{}{}{}", type_str, colon, bounds_str)
|
||||
}
|
||||
rewrite_assign_rhs(context, lhs, bounds, shape)?
|
||||
}
|
||||
ast::WherePredicate::RegionPredicate(ast::WhereRegionPredicate {
|
||||
ref lifetime,
|
||||
ref bounds,
|
||||
..
|
||||
}) => rewrite_bounded_lifetime(lifetime, bounds.iter(), context, shape)?,
|
||||
}) => rewrite_bounded_lifetime(lifetime, bounds, context, shape)?,
|
||||
ast::WherePredicate::EqPredicate(ast::WhereEqPredicate {
|
||||
ref lhs_ty,
|
||||
ref rhs_ty,
|
||||
..
|
||||
}) => {
|
||||
let lhs_ty_str = lhs_ty.rewrite(context, shape)?;
|
||||
// 3 = " = ".len()
|
||||
let used_width = 3 + lhs_ty_str.len();
|
||||
let budget = shape.width.checked_sub(used_width)?;
|
||||
let rhs_ty_str =
|
||||
rhs_ty.rewrite(context, Shape::legacy(budget, shape.indent + used_width))?;
|
||||
format!("{} = {}", lhs_ty_str, rhs_ty_str)
|
||||
let lhs_ty_str = lhs_ty.rewrite(context, shape).map(|lhs| lhs + " =")?;
|
||||
rewrite_assign_rhs(context, lhs_ty_str, &**rhs_ty, shape)?
|
||||
}
|
||||
};
|
||||
|
||||
@ -498,26 +470,23 @@ fn rewrite(&self, context: &RewriteContext, shape: Shape) -> Option<String> {
|
||||
|
||||
impl Rewrite for ast::LifetimeDef {
|
||||
fn rewrite(&self, context: &RewriteContext, shape: Shape) -> Option<String> {
|
||||
rewrite_bounded_lifetime(&self.lifetime, self.bounds.iter(), context, shape)
|
||||
rewrite_bounded_lifetime(&self.lifetime, &self.bounds, context, shape)
|
||||
}
|
||||
}
|
||||
|
||||
fn rewrite_bounded_lifetime<'b, I>(
|
||||
fn rewrite_bounded_lifetime(
|
||||
lt: &ast::Lifetime,
|
||||
bounds: I,
|
||||
bounds: &[ast::Lifetime],
|
||||
context: &RewriteContext,
|
||||
shape: Shape,
|
||||
) -> Option<String>
|
||||
where
|
||||
I: ExactSizeIterator<Item = &'b ast::Lifetime>,
|
||||
{
|
||||
) -> Option<String> {
|
||||
let result = lt.rewrite(context, shape)?;
|
||||
|
||||
if bounds.len() == 0 {
|
||||
Some(result)
|
||||
} else {
|
||||
let appendix = bounds
|
||||
.into_iter()
|
||||
.iter()
|
||||
.map(|b| b.rewrite(context, shape))
|
||||
.collect::<Option<Vec<_>>>()?;
|
||||
let colon = type_bound_colon(context);
|
||||
@ -526,7 +495,7 @@ fn rewrite_bounded_lifetime<'b, I>(
|
||||
"{}{}{}",
|
||||
result,
|
||||
colon,
|
||||
join_bounds(context, shape.sub_width(overhead)?, &appendix)
|
||||
join_bounds(context, shape.sub_width(overhead)?, bounds, &appendix, true)?
|
||||
);
|
||||
Some(result)
|
||||
}
|
||||
@ -552,12 +521,28 @@ fn rewrite(&self, _: &RewriteContext, _: Shape) -> Option<String> {
|
||||
}
|
||||
}
|
||||
|
||||
/// A simple wrapper over type param bounds in trait.
|
||||
#[derive(new)]
|
||||
pub struct TraitTyParamBounds<'a> {
|
||||
inner: &'a ast::TyParamBounds,
|
||||
}
|
||||
|
||||
impl<'a> Rewrite for TraitTyParamBounds<'a> {
|
||||
fn rewrite(&self, context: &RewriteContext, shape: Shape) -> Option<String> {
|
||||
let strs = self.inner
|
||||
.iter()
|
||||
.map(|b| b.rewrite(context, shape))
|
||||
.collect::<Option<Vec<_>>>()?;
|
||||
join_bounds(context, shape, self.inner, &strs, false)
|
||||
}
|
||||
}
|
||||
|
||||
impl Rewrite for ast::TyParamBounds {
|
||||
fn rewrite(&self, context: &RewriteContext, shape: Shape) -> Option<String> {
|
||||
let strs = self.iter()
|
||||
.map(|b| b.rewrite(context, shape))
|
||||
.collect::<Option<Vec<_>>>()?;
|
||||
Some(join_bounds(context, shape, &strs))
|
||||
join_bounds(context, shape, self, &strs, true)
|
||||
}
|
||||
}
|
||||
|
||||
@ -572,11 +557,7 @@ fn rewrite(&self, context: &RewriteContext, shape: Shape) -> Option<String> {
|
||||
result.push_str(&self.ident.to_string());
|
||||
if !self.bounds.is_empty() {
|
||||
result.push_str(type_bound_colon(context));
|
||||
let strs = self.bounds
|
||||
.iter()
|
||||
.map(|ty_bound| ty_bound.rewrite(context, shape))
|
||||
.collect::<Option<Vec<_>>>()?;
|
||||
result.push_str(&join_bounds(context, shape, &strs));
|
||||
result.push_str(&self.bounds.rewrite(context, shape)?)
|
||||
}
|
||||
if let Some(ref def) = self.default {
|
||||
let eq_str = match context.config.type_punctuation_density() {
|
||||
@ -794,20 +775,41 @@ fn rewrite_bare_fn(
|
||||
Some(result)
|
||||
}
|
||||
|
||||
pub fn join_bounds(context: &RewriteContext, shape: Shape, type_strs: &[String]) -> String {
|
||||
fn join_bounds<T>(
|
||||
context: &RewriteContext,
|
||||
shape: Shape,
|
||||
items: &[T],
|
||||
type_strs: &[String],
|
||||
need_indent: bool,
|
||||
) -> Option<String>
|
||||
where
|
||||
T: Rewrite,
|
||||
{
|
||||
// Try to join types in a single line
|
||||
let joiner = match context.config.type_punctuation_density() {
|
||||
TypeDensity::Compressed => "+",
|
||||
TypeDensity::Wide => " + ",
|
||||
};
|
||||
let result = type_strs.join(joiner);
|
||||
if result.contains('\n') || result.len() > shape.width {
|
||||
let joiner_indent = shape.indent.block_indent(context.config);
|
||||
let joiner = format!("{}+ ", joiner_indent.to_string_with_newline(context.config));
|
||||
type_strs.join(&joiner)
|
||||
} else {
|
||||
result
|
||||
if items.len() == 1 || (!result.contains('\n') && result.len() <= shape.width) {
|
||||
return Some(result);
|
||||
}
|
||||
|
||||
// We need to use multiple lines.
|
||||
let (type_strs, offset) = if need_indent {
|
||||
// Rewrite with additional indentation.
|
||||
let nested_shape = shape.block_indent(context.config.tab_spaces());
|
||||
let type_strs = items
|
||||
.iter()
|
||||
.map(|item| item.rewrite(context, nested_shape))
|
||||
.collect::<Option<Vec<_>>>()?;
|
||||
(type_strs, nested_shape.indent)
|
||||
} else {
|
||||
(type_strs.to_vec(), shape.indent)
|
||||
};
|
||||
|
||||
let joiner = format!("{}+ ", offset.to_string_with_newline(context.config));
|
||||
Some(type_strs.join(&joiner))
|
||||
}
|
||||
|
||||
pub fn can_be_overflowed_type(context: &RewriteContext, ty: &ast::Ty, len: usize) -> bool {
|
||||
|
Loading…
Reference in New Issue
Block a user