diff options
Diffstat (limited to 'src/types.rs')
| -rw-r--r-- | src/types.rs | 125 |
1 files changed, 53 insertions, 72 deletions
diff --git a/src/types.rs b/src/types.rs index 7dfc4337178..d2405f390f1 100644 --- a/src/types.rs +++ b/src/types.rs @@ -19,9 +19,10 @@ use syntax::symbol::keywords; use {Shape, Spanned}; use codemap::SpanUtils; -use lists::{format_item_list, itemize_list, format_fn_args}; +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; @@ -213,31 +214,25 @@ fn rewrite_segment(path_context: PathContext, "" }; - // 1 for < - let extra_offset = 1 + separator.len(); - // 1 for > - // TODO bad visual indent - let list_shape = try_opt!(try_opt!(shape.shrink_left(extra_offset)).sub_width(1)) - .visual_indent(0); - + let generics_shape = + generics_shape_from_config(context.config, shape, separator.len()); let items = itemize_list(context.codemap, param_list.into_iter(), ">", |param| param.get_span().lo, |param| param.get_span().hi, - |seg| seg.rewrite(context, list_shape), + |seg| seg.rewrite(context, generics_shape), list_lo, span_hi); - let list_str = try_opt!(format_item_list(items, list_shape, context.config)); + let generics_str = try_opt!(format_generics_item_list(context, + items, + generics_shape, + generics_shape.width)); // Update position of last bracket. *span_lo = next_span_lo; - if context.config.spaces_within_angle_brackets() && list_str.len() > 0 { - format!("{}< {} >", separator, list_str) - } else { - format!("{}<{}>", separator, list_str) - } + format!("{}{}", separator, generics_str) } ast::PathParameters::Parenthesized(ref data) => { let output = match data.output { @@ -367,22 +362,15 @@ impl Rewrite for ast::WherePredicate { .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< {} > {}{}{}", @@ -394,21 +382,14 @@ impl Rewrite for ast::WherePredicate { 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) } @@ -463,11 +444,11 @@ fn rewrite_bounded_lifetime<'b, I>(lt: &ast::Lifetime, .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) } } @@ -499,12 +480,8 @@ impl Rewrite for ast::Lifetime { 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) } } @@ -519,24 +496,12 @@ impl Rewrite for ast::TyParam { 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 { @@ -737,3 +702,19 @@ fn rewrite_bare_fn(bare_fn: &ast::BareFnTy, 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 + } +} |
