diff --git a/src/expr.rs b/src/expr.rs index dff1521f14a0..4bea5f4c0e19 100644 --- a/src/expr.rs +++ b/src/expr.rs @@ -16,12 +16,12 @@ use codemap::SpanUtils; use rewrite::{Rewrite, RewriteContext}; use lists::{write_list, itemize_list, ListFormatting, SeparatorTactic, ListTactic, - DefinitiveListTactic, definitive_tactic, ListItem, format_item_list, struct_lit_shape, + DefinitiveListTactic, definitive_tactic, ListItem, struct_lit_shape, struct_lit_tactic, shape_for_tactic, struct_lit_formatting}; use string::{StringFormat, rewrite_string}; use utils::{extra_offset, last_line_width, wrap_str, binary_search, first_line_width, semicolon_for_stmt, trimmed_last_line_width, left_most_sub_expr, stmt_expr, - colon_spaces, contains_skip, mk_sp, last_line_extendable}; + colon_spaces, contains_skip, mk_sp, last_line_extendable, paren_overhead}; use visitor::FmtVisitor; use config::{Config, IndentStyle, MultilineStyle, ControlBraceStyle, Style}; use comment::{FindUncommented, rewrite_comment, contains_comment, recover_comment_removed}; @@ -2217,7 +2217,7 @@ fn rewrite_call_args<'a, T>( context.config.trailing_comma() }, shape: shape, - ends_with_newline: false, + ends_with_newline: context.use_block_indent() && tactic == DefinitiveListTactic::Vertical, config: context.config, }; @@ -2436,14 +2436,6 @@ pub fn can_be_overflowed_expr(context: &RewriteContext, expr: &ast::Expr, args_l } } -fn paren_overhead(context: &RewriteContext) -> usize { - if context.config.spaces_within_parens() { - 4 - } else { - 2 - } -} - pub fn wrap_args_with_parens( context: &RewriteContext, args_str: &str, @@ -2813,7 +2805,21 @@ fn rewrite_tuple_in_visual_indent_style<'a, T>( list_lo, span.hi - BytePos(1), ); - let list_str = try_opt!(format_item_list(items, nested_shape, context.config)); + let item_vec: Vec<_> = items.collect(); + let tactic = definitive_tactic( + &item_vec, + ListTactic::HorizontalVertical, + nested_shape.width, + ); + let fmt = ListFormatting { + tactic: tactic, + separator: ",", + trailing_separator: SeparatorTactic::Never, + shape: shape, + ends_with_newline: false, + config: context.config, + }; + let list_str = try_opt!(write_list(&item_vec, &fmt)); if context.config.spaces_within_parens() && list_str.len() > 0 { Some(format!("( {} )", list_str)) @@ -3023,3 +3029,14 @@ fn can_be_overflowed(&self, context: &RewriteContext, len: usize) -> bool { can_be_overflowed_pat(context, self, len) } } + +impl<'a> ToExpr for ast::StructField { + fn to_expr(&self) -> Option<&ast::Expr> { + None + } + + #[allow(unused_variables)] + fn can_be_overflowed(&self, context: &RewriteContext, len: usize) -> bool { + false + } +} diff --git a/src/items.rs b/src/items.rs index 844ebf7f13bd..aa19e4238a50 100644 --- a/src/items.rs +++ b/src/items.rs @@ -15,9 +15,10 @@ use utils::{format_mutability, format_visibility, contains_skip, end_typaram, wrap_str, last_line_width, format_unsafety, trim_newlines, stmt_expr, semicolon_for_expr, trimmed_last_line_width, colon_spaces, mk_sp}; -use lists::{write_list, itemize_list, definitive_tactic, ListItem, ListFormatting, - SeparatorTactic, DefinitiveListTactic, ListTactic}; -use expr::{format_expr, is_empty_block, is_simple_block_stmt, rewrite_assign_rhs, ExprType}; +use lists::{write_list, itemize_list, ListItem, ListFormatting, SeparatorTactic, + DefinitiveListTactic, ListTactic, definitive_tactic}; +use expr::{format_expr, is_empty_block, is_simple_block_stmt, rewrite_assign_rhs, + rewrite_call_inner, ExprType}; use comment::{FindUncommented, contains_comment, rewrite_comment, recover_comment_removed}; use visitor::FmtVisitor; use rewrite::{Rewrite, RewriteContext}; @@ -1216,91 +1217,19 @@ fn format_tuple_struct( } result.push(')'); } else { - let (tactic, item_indent) = match context.config.fn_args_layout() { - IndentStyle::Visual => { - // 1 = `(` - ( - ListTactic::HorizontalVertical, - offset.block_only() + result.len() + 1, - ) - } - IndentStyle::Block => { - ( - if result.contains('\n') { - ListTactic::Vertical - } else { - ListTactic::HorizontalVertical - }, - offset.block_only().block_indent(&context.config), - ) - } - }; // 3 = `();` - let item_budget = try_opt!( - context - .config - .max_width() - .checked_sub(item_indent.width() + 3) + let body = try_opt!( + rewrite_call_inner( + context, + "", + &fields.iter().map(|field| field).collect::>()[..], + span, + Shape::legacy(context.budget(last_line_width(&result) + 3), offset), + context.config.fn_call_width(), + false, + ).ok() ); - - let items = itemize_list( - context.codemap, - fields.iter(), - ")", - |field| { - // Include attributes and doc comments, if present - if !field.attrs.is_empty() { - field.attrs[0].span.lo - } else { - field.span.lo - } - }, - |field| field.ty.span.hi, - |field| { - rewrite_struct_field(context, field, Shape::legacy(item_budget, item_indent), 0) - }, - context.codemap.span_after(span, "("), - span.hi, - ); - let body_budget = try_opt!( - context - .config - .max_width() - .checked_sub(offset.block_only().width() + last_line_width(&result) + 3) - ); - - let item_vec: Vec<_> = items.collect(); - let tactic = definitive_tactic(&item_vec, tactic, body_budget); - let fmt = ListFormatting { - tactic: tactic, - separator: ",", - trailing_separator: context.config.trailing_comma(), - shape: Shape::indented(item_indent, context.config), - ends_with_newline: false, - config: context.config, - }; - let body = try_opt!(write_list(&item_vec, &fmt)); - - if context.config.fn_args_layout() == IndentStyle::Visual || !body.contains('\n') { - result.push('('); - if context.config.spaces_within_parens() && body.len() > 0 { - result.push(' '); - } - - result.push_str(&body); - - if context.config.spaces_within_parens() && body.len() > 0 { - result.push(' '); - } - result.push(')'); - } else { - result.push_str("(\n"); - result.push_str(&item_indent.to_string(&context.config)); - result.push_str(&body); - result.push('\n'); - result.push_str(&offset.block_only().to_string(&context.config)); - result.push(')'); - } + result.push_str(&body); } if !where_clause_str.is_empty() && !where_clause_str.contains('\n') && @@ -2422,7 +2351,7 @@ fn rewrite_generics( span: Span, ) -> Option { let g_shape = try_opt!(generics_shape_from_config(context.config, shape, 0)); - let one_line_width = try_opt!(shape.width.checked_sub(2)); + let one_line_width = shape.width.checked_sub(2).unwrap_or(0); rewrite_generics_inner(context, generics, g_shape, one_line_width, span).or_else(|| { rewrite_generics_inner(context, generics, g_shape, 0, span) }) @@ -2497,8 +2426,11 @@ pub fn format_generics_item_list( { let item_vec = items.collect::>(); + let tactic = definitive_tactic(&item_vec, ListTactic::HorizontalVertical, one_line_budget); + let ends_with_newline = context.config.generics_indent() == IndentStyle::Block && + tactic == DefinitiveListTactic::Vertical; let fmt = ListFormatting { - tactic: definitive_tactic(&item_vec, ListTactic::HorizontalVertical, one_line_budget), + tactic: tactic, separator: ",", trailing_separator: if context.config.generics_indent() == IndentStyle::Visual { SeparatorTactic::Never @@ -2506,7 +2438,7 @@ pub fn format_generics_item_list( context.config.trailing_comma() }, shape: shape, - ends_with_newline: false, + ends_with_newline: ends_with_newline, config: context.config, }; @@ -2735,8 +2667,9 @@ fn format_generics( force_same_line_brace: bool, offset: Indent, span: Span, + used_width: usize, ) -> Option { - let shape = Shape::indented(offset, context.config); + let shape = Shape::legacy(context.budget(used_width + offset.width()), offset); let mut result = try_opt!(rewrite_generics(context, generics, shape, span)); if !generics.where_clause.predicates.is_empty() || result.contains('\n') { diff --git a/src/lists.rs b/src/lists.rs index d6cb00b55cd3..5e3d00076f79 100644 --- a/src/lists.rs +++ b/src/lists.rs @@ -14,7 +14,7 @@ use syntax::codemap::{CodeMap, BytePos}; use {Indent, Shape}; -use comment::{FindUncommented, rewrite_comment, find_comment_end}; +use comment::{find_comment_end, rewrite_comment, FindUncommented}; use config::{Config, IndentStyle}; use rewrite::RewriteContext; use utils::mk_sp; @@ -68,31 +68,6 @@ pub struct ListFormatting<'a> { pub config: &'a Config, } -pub fn format_item_list(items: I, shape: Shape, config: &Config) -> Option -where - I: Iterator, -{ - list_helper(items, shape, config, ListTactic::HorizontalVertical) -} - -pub fn list_helper(items: I, shape: Shape, config: &Config, tactic: ListTactic) -> Option -where - I: Iterator, -{ - let item_vec: Vec<_> = items.collect(); - let tactic = definitive_tactic(&item_vec, tactic, shape.width); - let fmt = ListFormatting { - tactic: tactic, - separator: ",", - trailing_separator: SeparatorTactic::Never, - shape: shape, - ends_with_newline: false, - config: config, - }; - - write_list(&item_vec, &fmt) -} - impl AsRef for ListItem { fn as_ref(&self) -> &ListItem { self @@ -118,10 +93,13 @@ pub fn is_multiline(&self) -> bool { .map_or(false, |s| s.contains('\n')) } - pub fn has_line_pre_comment(&self) -> bool { + pub fn has_comment(&self) -> bool { self.pre_comment .as_ref() - .map_or(false, |comment| comment.starts_with("//")) + .map_or(false, |comment| comment.starts_with("//")) || + self.post_comment + .as_ref() + .map_or(false, |comment| comment.starts_with("//")) } pub fn from_str>(s: S) -> ListItem { @@ -150,7 +128,7 @@ pub fn definitive_tactic(items: I, tactic: ListTactic, width: usize) -> De let pre_line_comments = items .clone() .into_iter() - .any(|item| item.as_ref().has_line_pre_comment()); + .any(|item| item.as_ref().has_comment()); let limit = match tactic { _ if pre_line_comments => return DefinitiveListTactic::Vertical, diff --git a/src/rewrite.rs b/src/rewrite.rs index 5c1236104b52..6a7167537c97 100644 --- a/src/rewrite.rs +++ b/src/rewrite.rs @@ -45,4 +45,8 @@ pub fn snippet(&self, span: Span) -> String { pub fn use_block_indent(&self) -> bool { self.config.fn_call_style() == IndentStyle::Block || self.use_block } + + pub fn budget(&self, used_width: usize) -> usize { + self.config.max_width().checked_sub(used_width).unwrap_or(0) + } } diff --git a/src/utils.rs b/src/utils.rs index dc5dee6ba0d9..bc46316d39b8 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -393,6 +393,15 @@ pub fn colon_spaces(before: bool, after: bool) -> &'static str { } } +#[inline] +pub fn paren_overhead(context: &RewriteContext) -> usize { + if context.config.spaces_within_parens() { + 4 + } else { + 2 + } +} + #[test] fn bin_search_test() { let closure = |i| match i {