diff --git a/src/bin/main.rs b/src/bin/main.rs index 962b315de05..b7bb92c858f 100644 --- a/src/bin/main.rs +++ b/src/bin/main.rs @@ -36,7 +36,8 @@ fn main() { let exit_code = match execute(&opts) { Ok((write_mode, summary)) => { - if summary.has_operational_errors() || summary.has_parsing_errors() + if summary.has_operational_errors() + || summary.has_parsing_errors() || (summary.has_diff && write_mode == WriteMode::Check) { 1 diff --git a/src/chains.rs b/src/chains.rs index 2f05f4a2c46..c602ed7b3e5 100644 --- a/src/chains.rs +++ b/src/chains.rs @@ -265,7 +265,8 @@ pub fn rewrite_chain(expr: &ast::Expr, context: &RewriteContext, shape: Shape) - nested_shape.indent.to_string_with_newline(context.config) }; - let first_connector = if is_small_parent || fits_single_line + let first_connector = if is_small_parent + || fits_single_line || last_line_extendable(&parent_rewrite) || context.config.indent_style() == IndentStyle::Visual { @@ -275,7 +276,8 @@ pub fn rewrite_chain(expr: &ast::Expr, context: &RewriteContext, shape: Shape) - }; let result = if is_small_parent && rewrites.len() > 1 { - let second_connector = if fits_single_line || rewrites[1] == "?" + let second_connector = if fits_single_line + || rewrites[1] == "?" || last_line_extendable(&rewrites[0]) || context.config.indent_style() == IndentStyle::Visual { diff --git a/src/closures.rs b/src/closures.rs index 20ba0118f5f..c9372248f05 100644 --- a/src/closures.rs +++ b/src/closures.rs @@ -109,8 +109,10 @@ fn get_inner_expr<'a>( // Figure out if a block is necessary. fn needs_block(block: &ast::Block, prefix: &str, context: &RewriteContext) -> bool { - is_unsafe_block(block) || block.stmts.len() > 1 - || block_contains_comment(block, context.codemap) || prefix.contains('\n') + is_unsafe_block(block) + || block.stmts.len() > 1 + || block_contains_comment(block, context.codemap) + || prefix.contains('\n') } // Rewrite closure with a single expression wrapping its body with block. diff --git a/src/comment.rs b/src/comment.rs index 4a0abc2b099..49f8d1698e1 100644 --- a/src/comment.rs +++ b/src/comment.rs @@ -579,7 +579,9 @@ fn light_rewrite_comment( /// Does not trim all whitespace. If a single space is trimmed from the left of the string, /// this function returns true. fn left_trim_comment_line<'a>(line: &'a str, style: &CommentStyle) -> (&'a str, bool) { - if line.starts_with("//! ") || line.starts_with("/// ") || line.starts_with("/*! ") + if line.starts_with("//! ") + || line.starts_with("/// ") + || line.starts_with("/*! ") || line.starts_with("/** ") { (&line[4..], true) @@ -589,13 +591,18 @@ fn left_trim_comment_line<'a>(line: &'a str, style: &CommentStyle) -> (&'a str, } else { (&line[opener.trim_right().len()..], false) } - } else if line.starts_with("/* ") || line.starts_with("// ") || line.starts_with("//!") - || line.starts_with("///") || line.starts_with("** ") + } else if line.starts_with("/* ") + || line.starts_with("// ") + || line.starts_with("//!") + || line.starts_with("///") + || line.starts_with("** ") || line.starts_with("/*!") || (line.starts_with("/**") && !line.starts_with("/**/")) { (&line[3..], line.chars().nth(2).unwrap() == ' ') - } else if line.starts_with("/*") || line.starts_with("* ") || line.starts_with("//") + } else if line.starts_with("/*") + || line.starts_with("* ") + || line.starts_with("//") || line.starts_with("**") { (&line[2..], line.chars().nth(1).unwrap() == ' ') diff --git a/src/config/summary.rs b/src/config/summary.rs index c906c77506f..9f339b61be7 100644 --- a/src/config/summary.rs +++ b/src/config/summary.rs @@ -90,7 +90,9 @@ impl Summary { } pub fn has_no_errors(&self) -> bool { - !(self.has_operational_errors || self.has_parsing_errors || self.has_formatting_errors + !(self.has_operational_errors + || self.has_parsing_errors + || self.has_formatting_errors || self.has_diff) } diff --git a/src/expr.rs b/src/expr.rs index 2116ef03fd2..4ca1bbb22e3 100644 --- a/src/expr.rs +++ b/src/expr.rs @@ -474,8 +474,10 @@ where .map(|first_line| first_line.ends_with('{')) .unwrap_or(false); if !rhs_result.contains('\n') || allow_same_line { - let one_line_width = last_line_width(&lhs_result) + pp.infix.len() - + first_line_width(rhs_result) + pp.suffix.len(); + let one_line_width = last_line_width(&lhs_result) + + pp.infix.len() + + first_line_width(rhs_result) + + pp.suffix.len(); if one_line_width <= shape.width { return Some(format!( "{}{}{}{}", @@ -558,7 +560,9 @@ fn rewrite_empty_block( let user_str = user_str.trim(); if user_str.starts_with('{') && user_str.ends_with('}') { let comment_str = user_str[1..user_str.len() - 1].trim(); - if block.stmts.is_empty() && !comment_str.contains('\n') && !comment_str.starts_with("//") + if block.stmts.is_empty() + && !comment_str.contains('\n') + && !comment_str.starts_with("//") && comment_str.len() + 4 <= shape.width { return Some(format!("{}{{ {} }}", prefix, comment_str)); @@ -1241,8 +1245,10 @@ pub fn is_simple_block( attrs: Option<&[ast::Attribute]>, codemap: &CodeMap, ) -> bool { - (block.stmts.len() == 1 && stmt_is_expr(&block.stmts[0]) - && !block_contains_comment(block, codemap) && attrs.map_or(true, |a| a.is_empty())) + (block.stmts.len() == 1 + && stmt_is_expr(&block.stmts[0]) + && !block_contains_comment(block, codemap) + && attrs.map_or(true, |a| a.is_empty())) } /// Checks whether a block contains at most one statement or expression, and no @@ -1252,7 +1258,8 @@ pub fn is_simple_block_stmt( attrs: Option<&[ast::Attribute]>, codemap: &CodeMap, ) -> bool { - block.stmts.len() <= 1 && !block_contains_comment(block, codemap) + block.stmts.len() <= 1 + && !block_contains_comment(block, codemap) && attrs.map_or(true, |a| a.is_empty()) } @@ -1263,7 +1270,8 @@ pub fn is_empty_block( attrs: Option<&[ast::Attribute]>, codemap: &CodeMap, ) -> bool { - block.stmts.is_empty() && !block_contains_comment(block, codemap) + block.stmts.is_empty() + && !block_contains_comment(block, codemap) && attrs.map_or(true, |a| inner_attributes(a).is_empty()) } @@ -1778,7 +1786,8 @@ pub fn wrap_struct_field( one_line_width: usize, ) -> String { if context.config.indent_style() == IndentStyle::Block - && (fields_str.contains('\n') || !context.config.struct_lit_single_line() + && (fields_str.contains('\n') + || !context.config.struct_lit_single_line() || fields_str.len() > one_line_width) { format!( @@ -2104,7 +2113,8 @@ fn choose_rhs( } pub fn prefer_next_line(orig_rhs: &str, next_line_rhs: &str, rhs_tactics: RhsTactics) -> bool { - rhs_tactics == RhsTactics::ForceNextLine || !next_line_rhs.contains('\n') + rhs_tactics == RhsTactics::ForceNextLine + || !next_line_rhs.contains('\n') || count_newlines(orig_rhs) > count_newlines(next_line_rhs) + 1 } diff --git a/src/imports.rs b/src/imports.rs index 05b10519d45..3d7ad0ab1b5 100644 --- a/src/imports.rs +++ b/src/imports.rs @@ -489,7 +489,9 @@ impl UseTree { } fn share_prefix(&self, other: &UseTree) -> bool { - if self.path.is_empty() || other.path.is_empty() || self.attrs.is_some() + if self.path.is_empty() + || other.path.is_empty() + || self.attrs.is_some() || !self.same_visibility(other) { false diff --git a/src/items.rs b/src/items.rs index 08bdfe0295f..72954513908 100644 --- a/src/items.rs +++ b/src/items.rs @@ -313,7 +313,8 @@ impl<'a> FmtVisitor<'a> { rewrite_fn_base(&context, indent, ident, fn_sig, span, newline_brace, true)?; // 2 = ` {` - if self.config.brace_style() == BraceStyle::AlwaysNextLine || force_newline_brace + if self.config.brace_style() == BraceStyle::AlwaysNextLine + || force_newline_brace || last_line_width(&result) + 2 > self.shape().width { newline_brace = true; @@ -376,7 +377,8 @@ impl<'a> FmtVisitor<'a> { let codemap = self.get_context().codemap; - if self.config.empty_item_single_line() && is_empty_block(block, None, codemap) + if self.config.empty_item_single_line() + && is_empty_block(block, None, codemap) && self.block_indent.width() + fn_str.len() + 2 <= self.config.max_width() { return Some(format!("{}{{}}", fn_str)); @@ -755,7 +757,9 @@ fn is_impl_single_line( let open_pos = snippet.find_uncommented("{")? + 1; Some( - context.config.empty_item_single_line() && items.is_empty() && !result.contains('\n') + context.config.empty_item_single_line() + && items.is_empty() + && !result.contains('\n') && result.len() + where_clause_str.len() <= context.config.max_width() && !contains_comment(&snippet[open_pos..]), ) @@ -1194,7 +1198,8 @@ pub fn format_struct_struct( // 1 = `}` let overhead = if fields.is_empty() { 1 } else { 0 }; let total_width = result.len() + generics_str.len() + overhead; - if !generics_str.is_empty() && !generics_str.contains('\n') + if !generics_str.is_empty() + && !generics_str.contains('\n') && total_width > context.config.max_width() { result.push('\n'); @@ -1223,7 +1228,9 @@ pub fn format_struct_struct( one_line_budget, )?; - if !items_str.contains('\n') && !result.contains('\n') && items_str.len() <= one_line_budget + if !items_str.contains('\n') + && !result.contains('\n') + && items_str.len() <= one_line_budget && !last_line_contains_single_line_comment(&items_str) { Some(format!("{} {} }}", result, items_str)) @@ -1904,7 +1911,8 @@ fn rewrite_fn_base( } else { result.push('('); } - if context.config.spaces_within_parens_and_brackets() && !fd.inputs.is_empty() + if context.config.spaces_within_parens_and_brackets() + && !fd.inputs.is_empty() && result.ends_with('(') { result.push(' ') @@ -2478,8 +2486,10 @@ fn rewrite_where_clause_rfc_style( let newline_after_where = comment_separator(&comment_after, clause_shape); // 6 = `where ` - let clause_sep = if where_clause_option.compress_where && comment_before.is_empty() - && comment_after.is_empty() && !preds_str.contains('\n') + let clause_sep = if where_clause_option.compress_where + && comment_before.is_empty() + && comment_after.is_empty() + && !preds_str.contains('\n') && 6 + preds_str.len() <= shape.width || where_single_line { Cow::from(" ") @@ -2590,7 +2600,8 @@ fn rewrite_where_clause( } else { terminator.len() }; - if density == Density::Tall || preds_str.contains('\n') + if density == Density::Tall + || preds_str.contains('\n') || shape.indent.width() + " where ".len() + preds_str.len() + end_length > shape.width { Some(format!( @@ -2682,7 +2693,8 @@ fn format_generics( || (generics.where_clause.predicates.is_empty() && trimmed_last_line_width(&result) == 1) } else { - brace_pos == BracePos::ForceSameLine || trimmed_last_line_width(&result) == 1 + brace_pos == BracePos::ForceSameLine + || trimmed_last_line_width(&result) == 1 || brace_style != BraceStyle::AlwaysNextLine }; if brace_pos == BracePos::None { diff --git a/src/lib.rs b/src/lib.rs index ec8646acc1c..71cf74f6022 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -490,7 +490,8 @@ fn format_lines( // Check for any line width errors we couldn't correct. let error_kind = ErrorKind::LineOverflow(line_len, config.max_width()); - if line_len > config.max_width() && !is_skipped_line(cur_line, skipped_range) + if line_len > config.max_width() + && !is_skipped_line(cur_line, skipped_range) && should_report_error(config, kind, is_string, error_kind) { errors.push(FormattingError { @@ -905,7 +906,8 @@ pub fn format_and_emit_report(input: Input, config: &Config) -> FmtResult { match report.print_warnings_fancy(term::stderr().unwrap()) { diff --git a/src/lists.rs b/src/lists.rs index 9e5ea33d296..433beac44ee 100644 --- a/src/lists.rs +++ b/src/lists.rs @@ -192,7 +192,8 @@ where let total_sep_len = sep.len() * sep_count.checked_sub(1).unwrap_or(0); let real_total = total_width + total_sep_len; - if real_total <= limit && !pre_line_comments + if real_total <= limit + && !pre_line_comments && !items.into_iter().any(|item| item.as_ref().is_multiline()) { DefinitiveListTactic::Horizontal @@ -404,8 +405,10 @@ where if !starts_with_newline(comment) { let mut comment_alignment = post_comment_alignment(item_max_width, inner_item.len()); - if first_line_width(&formatted_comment) + last_line_width(&result) - + comment_alignment + 1 > formatting.config.max_width() + if first_line_width(&formatted_comment) + + last_line_width(&result) + + comment_alignment + + 1 > formatting.config.max_width() { item_max_width = None; formatted_comment = rewrite_post_comment(&mut item_max_width)?; @@ -431,7 +434,9 @@ where item_max_width = None; } - if formatting.preserve_newline && !last && tactic == DefinitiveListTactic::Vertical + if formatting.preserve_newline + && !last + && tactic == DefinitiveListTactic::Vertical && item.new_lines { item_max_width = None; @@ -458,7 +463,8 @@ where let item = item.as_ref(); let inner_item_width = item.inner_as_ref().len(); if !first - && (item.is_different_group() || item.post_comment.is_none() + && (item.is_different_group() + || item.post_comment.is_none() || inner_item_width + overhead > max_budget) { return max_width; diff --git a/src/macros.rs b/src/macros.rs index 1fc150e1256..3da0a4a5c3a 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -269,7 +269,8 @@ pub fn rewrite_macro_inner( let nested_shape = mac_shape.block_indent(context.config.tab_spaces()); let lhs = arg_vec[0].rewrite(context, nested_shape)?; let rhs = arg_vec[1].rewrite(context, nested_shape)?; - if !lhs.contains('\n') && !rhs.contains('\n') + if !lhs.contains('\n') + && !rhs.contains('\n') && lhs.len() + rhs.len() + total_overhead <= shape.width { Some(format!("{}{}{}; {}{}", macro_name, lbr, lhs, rhs, rbr)) diff --git a/src/matches.rs b/src/matches.rs index bc092b1a718..0bbdbe62017 100644 --- a/src/matches.rs +++ b/src/matches.rs @@ -498,7 +498,8 @@ fn rewrite_guard( fn nop_block_collapse(block_str: Option, budget: usize) -> Option { debug!("nop_block_collapse {:?} {}", block_str, budget); block_str.map(|block_str| { - if block_str.starts_with('{') && budget >= 2 + if block_str.starts_with('{') + && budget >= 2 && (block_str[1..].find(|c: char| !c.is_whitespace()).unwrap() == block_str.len() - 2) { "{}".to_owned() diff --git a/src/overflow.rs b/src/overflow.rs index 96bebc50bfd..977dbbbb5f4 100644 --- a/src/overflow.rs +++ b/src/overflow.rs @@ -235,7 +235,8 @@ impl<'a, T: 'a + Rewrite + ToExpr + Spanned> Context<'a, T> { fn try_overflow_last_item(&self, list_items: &mut Vec) -> DefinitiveListTactic { // 1 = "(" - let combine_arg_with_callee = self.items.len() == 1 && self.items[0].to_expr().is_some() + let combine_arg_with_callee = self.items.len() == 1 + && self.items[0].to_expr().is_some() && self.ident.len() + 1 <= self.context.config.tab_spaces(); let overflow_last = combine_arg_with_callee || can_be_overflowed(self.context, self.items); @@ -311,7 +312,9 @@ impl<'a, T: 'a + Rewrite + ToExpr + Spanned> Context<'a, T> { // Use horizontal layout for a function with a single argument as long as // everything fits in a single line. // `self.one_line_width == 0` means vertical layout is forced. - if self.items.len() == 1 && self.one_line_width != 0 && !list_items[0].has_comment() + if self.items.len() == 1 + && self.one_line_width != 0 + && !list_items[0].has_comment() && !list_items[0].inner_as_ref().contains('\n') && ::lists::total_item_width(&list_items[0]) <= self.one_line_width { @@ -462,7 +465,8 @@ impl<'a, T: 'a + Rewrite + ToExpr + Spanned> Context<'a, T> { let (extendable, items_str) = self.rewrite_items()?; // If we are using visual indent style and failed to format, retry with block indent. - if !self.context.use_block_indent() && need_block_indent(&items_str, self.nested_shape) + if !self.context.use_block_indent() + && need_block_indent(&items_str, self.nested_shape) && !extendable { self.context.use_block.replace(true); diff --git a/src/types.rs b/src/types.rs index 149769c5df7..6ffb9cd5c7e 100644 --- a/src/types.rs +++ b/src/types.rs @@ -230,7 +230,8 @@ fn rewrite_segment( if let Some(ref params) = segment.parameters { match **params { ast::PathParameters::AngleBracketed(ref data) - if !data.lifetimes.is_empty() || !data.types.is_empty() + if !data.lifetimes.is_empty() + || !data.types.is_empty() || !data.bindings.is_empty() => { let param_list = data.lifetimes