use comment::{FindUncommented, contains_comment, rewrite_comment, recover_comment_removed};
use visitor::FmtVisitor;
use rewrite::{Rewrite, RewriteContext};
-use config::{Config, IndentStyle, Density, ReturnIndent, BraceStyle, Style, TypeDensity};
+use config::{Config, IndentStyle, Density, ReturnIndent, BraceStyle, Style};
+use types::join_bounds;
use syntax::{ast, abi, ptr, symbol};
use syntax::codemap::{Span, BytePos};
context.config),
0);
let generics_str =
- try_opt!(rewrite_generics(context, generics, shape, shape.width, mk_sp(lo, hi)));
+ try_opt!(rewrite_generics_inner(context, generics, shape, shape.width, mk_sp(lo, hi)));
let polarity_str = if polarity == ast::ImplPolarity::Negative {
"!"
&mut result);
if !success {
let generics_str =
- try_opt!(rewrite_generics(context, generics, shape, 0, mk_sp(lo, hi)));
+ try_opt!(rewrite_generics_inner(context, generics, shape, 0, mk_sp(lo, hi)));
if !format_trait_ref_then_update_result(context,
&trait_ref,
offset,
let body_lo = context.codemap.span_after(item.span, "{");
- let generics_indent = offset + last_line_width(&result);
- let shape = generics_shape_from_config(context.config,
- Shape::indented(generics_indent, context.config),
- 0);
- let generics_str = try_opt!(rewrite_generics(context,
- generics,
- shape,
- shape.width,
- mk_sp(item.span.lo, body_lo)));
+ let shape = Shape::indented(offset + last_line_width(&result), context.config);
+ let generics_str =
+ try_opt!(rewrite_generics(context, generics, shape, mk_sp(item.span.lo, body_lo)));
result.push_str(&generics_str);
let trait_bound_str =
let where_clause_str = match generics {
Some(generics) => {
- let generics_indent = offset + last_line_width(&header_str);
- let shape = generics_shape_from_config(context.config,
- Shape::indented(generics_indent,
- context.config),
- 0);
- let generics_str = try_opt!(rewrite_generics(context,
- generics,
- shape,
- shape.width,
- mk_sp(span.lo, body_lo)));
+ let shape = Shape::indented(offset + last_line_width(&header_str), context.config);
+ let g_span = mk_sp(span.lo, body_lo);
+ let generics_str = try_opt!(rewrite_generics(context, generics, shape, g_span));
result.push_str(&generics_str);
let where_budget = try_opt!(context
result.push_str("type ");
result.push_str(&ident.to_string());
- let generics_indent = indent + result.len();
- let generics_span = mk_sp(context.codemap.span_after(span, "type"), ty.span.lo);
- let shape = generics_shape_from_config(context.config,
- try_opt!(Shape::indented(generics_indent,
- context.config)
- .sub_width(" =".len())),
- 0);
- let generics_str =
- try_opt!(rewrite_generics(context, generics, shape, shape.width, generics_span));
-
+ // 2 = `= `
+ let shape = try_opt!(Shape::indented(indent + result.len(), context.config).sub_width(2));
+ let g_span = mk_sp(context.codemap.span_after(span, "type"), ty.span.lo);
+ let generics_str = try_opt!(rewrite_generics(context, generics, shape, g_span));
result.push_str(&generics_str);
let where_budget = try_opt!(context
let prefix = format!("type {}", ident);
let type_bounds_str = if let Some(ty_param_bounds) = ty_param_bounds_opt {
- let joiner = match context.config.type_punctuation_density() {
- TypeDensity::Compressed => "+",
- TypeDensity::Wide => " + ",
- };
+ let shape = Shape::legacy(context.config.max_width(), indent);
let bounds: &[_] = ty_param_bounds;
- let bound_str =
- try_opt!(bounds
- .iter()
- .map(|ty_bound| {
- ty_bound.rewrite(context,
- Shape::legacy(context.config.max_width(),
- indent))
- })
- .collect::<Option<Vec<_>>>())
- .join(joiner);
+ let bound_str = try_opt!(bounds
+ .iter()
+ .map(|ty_bound| ty_bound.rewrite(context, shape))
+ .collect::<Option<Vec<_>>>());
if bounds.len() > 0 {
- format!(": {}", bound_str)
+ format!(": {}", join_bounds(context, shape, &bound_str))
} else {
String::new()
}
result.push_str(&ident.to_string());
// Generics.
- let generics_indent = indent + last_line_width(&result);
- let generics_span = mk_sp(span.lo, span_for_return(&fd.output).lo);
- let shape = generics_shape_from_config(context.config,
- Shape::indented(generics_indent, context.config),
- 0);
- let generics_str =
- try_opt!(rewrite_generics(context, generics, shape, shape.width, generics_span));
+ let shape = Shape::indented(indent + last_line_width(&result), context.config);
+ let g_span = mk_sp(span.lo, span_for_return(&fd.output).lo);
+ let generics_str = try_opt!(rewrite_generics(context, generics, shape, g_span));
result.push_str(&generics_str);
let snuggle_angle_bracket = generics_str
fn rewrite_generics(context: &RewriteContext,
generics: &ast::Generics,
shape: Shape,
- one_line_width: usize,
span: Span)
-> Option<String> {
+ let shape = generics_shape_from_config(context.config, shape, 0);
+ rewrite_generics_inner(context, generics, shape, shape.width, span)
+ .or_else(|| rewrite_generics_inner(context, generics, shape, 0, span))
+}
+
+fn rewrite_generics_inner(context: &RewriteContext,
+ generics: &ast::Generics,
+ shape: Shape,
+ one_line_width: usize,
+ span: Span)
+ -> Option<String> {
// FIXME: convert bounds to where clauses where they get too big or if
// there is a where clause at all.
let lifetimes: &[_] = &generics.lifetimes;
if bounds.is_empty() {
return Some(String::new());
}
- let joiner = match context.config.type_punctuation_density() {
- TypeDensity::Compressed => "+",
- TypeDensity::Wide => " + ",
- };
let bound_str = try_opt!(bounds
.iter()
.map(|ty_bound| ty_bound.rewrite(&context, shape))
- .collect::<Option<Vec<_>>>())
- .join(joiner);
-
- let mut result = String::new();
- result.push_str(": ");
- result.push_str(&bound_str);
- Some(result)
+ .collect::<Option<Vec<_>>>());
+ Some(format!(": {}", join_bounds(context, shape, &bound_str)))
}
fn rewrite_where_clause_rfc_style(context: &RewriteContext,
offset: Indent,
span: Span)
-> Option<String> {
- let shape =
- generics_shape_from_config(context.config, Shape::indented(offset, context.config), 0);
- let mut result = try_opt!(rewrite_generics(context, generics, shape, shape.width, span));
+ let shape = Shape::indented(offset, context.config);
+ let mut result = try_opt!(rewrite_generics(context, generics, shape, span));
if !generics.where_clause.predicates.is_empty() || result.contains('\n') {
let budget = try_opt!(context
use items::{format_generics_item_list, generics_shape_from_config};
use lists::{itemize_list, format_fn_args};
use rewrite::{Rewrite, RewriteContext};
-use utils::{extra_offset, format_mutability, colon_spaces, wrap_str, mk_sp};
+use utils::{extra_offset, format_mutability, colon_spaces, wrap_str, mk_sp, last_line_width};
use expr::{rewrite_unary_prefix, rewrite_pair, rewrite_tuple_type};
use config::TypeDensity;
.collect::<Option<Vec<_>>>())
.join(", ");
- let joiner = match context.config.type_punctuation_density() {
- TypeDensity::Compressed => "+",
- TypeDensity::Wide => " + ",
- };
// 6 = "for<> ".len()
let used_width = lifetime_str.len() + type_str.len() + colon.len() + 6;
- let budget = try_opt!(shape.width.checked_sub(used_width));
- let bounds_str: String = try_opt!(
- bounds
- .iter()
- .map(|ty_bound| {
- ty_bound.rewrite(context,
- Shape::legacy(budget, shape.indent + used_width))
- })
- .collect::<Option<Vec<_>>>()
- ).join(joiner);
+ let ty_shape = try_opt!(shape.block_left(used_width));
+ let bounds: Vec<_> =
+ try_opt!(bounds
+ .iter()
+ .map(|ty_bound| ty_bound.rewrite(context, ty_shape))
+ .collect());
+ let bounds_str = join_bounds(context, ty_shape, &bounds);
if context.config.spaces_within_angle_brackets() && lifetime_str.len() > 0 {
format!("for< {} > {}{}{}",
format!("for<{}> {}{}{}", lifetime_str, type_str, colon, bounds_str)
}
} else {
- let joiner = match context.config.type_punctuation_density() {
- TypeDensity::Compressed => "+",
- TypeDensity::Wide => " + ",
- };
let used_width = type_str.len() + colon.len();
- let budget = try_opt!(shape.width.checked_sub(used_width));
- let bounds_str: String = try_opt!(
- bounds
- .iter()
- .map(|ty_bound| {
- ty_bound.rewrite(context,
- Shape::legacy(budget, shape.indent + used_width))
- })
- .collect::<Option<Vec<_>>>()
- ).join(joiner);
+ let ty_shape = try_opt!(shape.block_left(used_width));
+ let bounds: Vec<_> =
+ try_opt!(bounds
+ .iter()
+ .map(|ty_bound| ty_bound.rewrite(context, ty_shape))
+ .collect());
+ let bounds_str = join_bounds(context, ty_shape, &bounds);
format!("{}{}{}", type_str, colon, bounds_str)
}
.map(|b| b.rewrite(context, shape))
.collect());
let colon = type_bound_colon(context);
- let joiner = match context.config.type_punctuation_density() {
- TypeDensity::Compressed => "+",
- TypeDensity::Wide => " + ",
- };
- let result = format!("{}{}{}", result, colon, appendix.join(joiner));
+ let overhead = last_line_width(&result) + colon.len();
+ let result = format!("{}{}{}",
+ result,
+ colon,
+ join_bounds(context, try_opt!(shape.sub_width(overhead)), &appendix));
wrap_str(result, context.config.max_width(), shape)
}
}
impl Rewrite for ast::TyParamBounds {
fn rewrite(&self, context: &RewriteContext, shape: Shape) -> Option<String> {
- let joiner = match context.config.type_punctuation_density() {
- TypeDensity::Compressed => "+",
- TypeDensity::Wide => " + ",
- };
let strs: Vec<_> = try_opt!(self.iter().map(|b| b.rewrite(context, shape)).collect());
- wrap_str(strs.join(joiner), context.config.max_width(), shape)
+ join_bounds(context, shape, &strs).rewrite(context, shape)
}
}
result.push_str(&attr_str);
result.push_str(&self.ident.to_string());
if !self.bounds.is_empty() {
- if context.config.space_before_bound() {
- result.push_str(" ");
- }
- result.push_str(":");
- if context.config.space_after_bound_colon() {
- result.push_str(" ");
- }
- let joiner = match context.config.type_punctuation_density() {
- TypeDensity::Compressed => "+",
- TypeDensity::Wide => " + ",
- };
- let bounds: String = try_opt!(self.bounds
- .iter()
- .map(|ty_bound| ty_bound.rewrite(context, shape))
- .collect::<Option<Vec<_>>>())
- .join(joiner);
-
- result.push_str(&bounds);
+ result.push_str(type_bound_colon(context));
+ let strs: Vec<_> = try_opt!(self.bounds
+ .iter()
+ .map(|ty_bound| ty_bound.rewrite(context, shape))
+ .collect());
+ result.push_str(&join_bounds(context, shape, &strs));
}
if let Some(ref def) = self.default {
Some(result)
}
+
+pub fn join_bounds(context: &RewriteContext, shape: Shape, type_strs: &Vec<String>) -> String {
+ // 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!("\n{}+ ", joiner_indent.to_string(context.config));
+ type_strs.join(&joiner)
+ } else {
+ result
+ }
+}