diff --git a/src/comment.rs b/src/comment.rs index d0eeba9a7c1..ff7558131d2 100644 --- a/src/comment.rs +++ b/src/comment.rs @@ -41,43 +41,44 @@ pub fn rewrite_comment(orig: &str, block_style: bool, width: usize, offset: usiz let line_breaks = s.chars().filter(|&c| c == '\n').count(); let (_, mut s) = s.lines() - .enumerate() - .map(|(i, mut line)| { - line = line.trim(); - // Drop old closer. - if i == line_breaks && line.ends_with("*/") && !line.starts_with("//") { - line = &line[..(line.len() - 2)]; - } + .enumerate() + .map(|(i, mut line)| { + line = line.trim(); + // Drop old closer. + if i == line_breaks && line.ends_with("*/") && !line.starts_with("//") { + line = &line[..(line.len() - 2)]; + } - line.trim_right() - }) - .map(left_trim_comment_line) - .map(|line| { - if line_breaks == 0 { - line.trim_left() - } else { - line - } - }) - .fold((true, opener.to_owned()), |(first, mut acc), line| { - if !first { - acc.push('\n'); - acc.push_str(&indent_str); - acc.push_str(line_start); - } + line.trim_right() + }) + .map(left_trim_comment_line) + .map(|line| { + if line_breaks == 0 { + line.trim_left() + } else { + line + } + }) + .fold((true, opener.to_owned()), + |(first, mut acc), line| { + if !first { + acc.push('\n'); + acc.push_str(&indent_str); + acc.push_str(line_start); + } - if line.len() > max_chars { - acc.push_str(&rewrite_string(line, &fmt)); - } else { - if line.len() == 0 { - acc.pop(); // Remove space if this is an empty comment. - } else { - acc.push_str(line); - } - } + if line.len() > max_chars { + acc.push_str(&rewrite_string(line, &fmt)); + } else { + if line.len() == 0 { + acc.pop(); // Remove space if this is an empty comment. + } else { + acc.push_str(line); + } + } - (false, acc) - }); + (false, acc) + }); s.push_str(closer); diff --git a/src/expr.rs b/src/expr.rs index 98b93a5faa7..c7dad3d2ccf 100644 --- a/src/expr.rs +++ b/src/expr.rs @@ -18,7 +18,7 @@ use StructLitStyle; use utils::{span_after, make_indent, extra_offset, first_line_width, last_line_width, wrap_str, binary_search}; use visitor::FmtVisitor; -use config::{BlockIndentStyle, MultilineStyle}; +use config::MultilineStyle; use comment::{FindUncommented, rewrite_comment, contains_comment}; use types::rewrite_path; use items::{span_lo_for_arg, span_hi_for_arg, rewrite_fn_input}; @@ -40,12 +40,6 @@ impl Rewrite for ast::Expr { } } ast::Expr_::ExprCall(ref callee, ref args) => { - // FIXME using byte lens instead of char lens (and probably all over the place too) - // 2 is for parens - let max_callee_width = try_opt!(width.checked_sub(2)); - let callee_str = try_opt!(callee.rewrite(context, max_callee_width, offset)); - let span = mk_sp(callee.span.hi, self.span.hi); - rewrite_call(context, &**callee, args, self.span, width, offset) } ast::Expr_::ExprParen(ref subexpr) => { @@ -214,8 +208,6 @@ fn rewrite_closure(capture: ast::CaptureClause, prefix.push_str(&ret_str); } - let closure_indent = closure_indent(context, offset); - // Try to format closure body as a single line expression without braces. if is_simple_block(body, context.codemap) && !prefix.contains('\n') { let (spacer, closer) = if ret_str.is_empty() { @@ -246,17 +238,16 @@ fn rewrite_closure(capture: ast::CaptureClause, // We couldn't format the closure body as a single line expression; fall // back to block formatting. - let inner_context = context.overflow_context(closure_indent - context.block_indent); let body_rewrite = body.expr .as_ref() .and_then(|body_expr| { if let ast::Expr_::ExprBlock(ref inner) = body_expr.node { - Some(inner.rewrite(&inner_context, 2, 0)) + Some(inner.rewrite(&context, 2, 0)) } else { None } }) - .unwrap_or_else(|| body.rewrite(&inner_context, 2, 0)); + .unwrap_or_else(|| body.rewrite(&context, 2, 0)); Some(format!("{} {}", prefix, try_opt!(body_rewrite))) } @@ -876,25 +867,21 @@ fn rewrite_string_lit(context: &RewriteContext, } pub fn rewrite_call(context: &RewriteContext, - callee: &R, - args: &[ptr::P], - span: Span, - width: usize, - offset: usize) - -> Option + callee: &R, + args: &[ptr::P], + span: Span, + width: usize, + offset: usize) + -> Option where R: Rewrite { + let closure = |callee_max_width| { + rewrite_call_inner(context, callee, callee_max_width, args, span, width, offset) + }; + // 2 is for parens let max_width = try_opt!(width.checked_sub(2)); - binary_search(1, max_width, |callee_max_width| { - rewrite_call_inner(context, - callee, - callee_max_width, - args, - span, - width, - offset) - }) + binary_search(1, max_width, closure) } fn rewrite_call_inner(context: &RewriteContext, @@ -1021,10 +1008,9 @@ fn rewrite_struct_lit<'a>(context: &RewriteContext, match *item { StructLitField::Regular(ref field) => field.span.lo, StructLitField::Base(ref expr) => { - let last_field_hi = fields.last().map_or(span.lo, - |field| { - field.span.hi - }); + let last_field_hi = fields.last() + .map_or(span.lo, + |field| field.span.hi); let snippet = context.snippet(mk_sp(last_field_hi, expr.span.lo)); let pos = snippet.find_uncommented("..").unwrap(); @@ -1074,11 +1060,10 @@ fn rewrite_struct_lit<'a>(context: &RewriteContext, let fields_str = try_opt!(write_list(&items.collect::>(), &fmt)); let format_on_newline = || { - let inner_indent = make_indent(context.block_indent + - context.config.tab_spaces); - let outer_indent = make_indent(context.block_indent); - Some(format!("{} {{\n{}{}\n{}}}", path_str, inner_indent, fields_str, outer_indent)) - }; + let inner_indent = make_indent(context.block_indent + context.config.tab_spaces); + let outer_indent = make_indent(context.block_indent); + Some(format!("{} {{\n{}{}\n{}}}", path_str, inner_indent, fields_str, outer_indent)) + }; match (context.config.struct_lit_style, context.config.struct_lit_multiline_style) { (StructLitStyle::Block, _) if fields_str.contains('\n') => format_on_newline(), diff --git a/src/imports.rs b/src/imports.rs index 4b08a8b35e1..1d215d022d1 100644 --- a/src/imports.rs +++ b/src/imports.rs @@ -150,10 +150,10 @@ pub fn rewrite_use_list(width: usize, let list_str = try_opt!(write_list(&items[first_index..], &fmt)); Some(if path_str.is_empty() { - format!("{{{}}}", list_str) - } else { - format!("{}::{{{}}}", path_str, list_str) - }) + format!("{{{}}}", list_str) + } else { + format!("{}::{{{}}}", path_str, list_str) + }) } // Returns true when self item was found. diff --git a/src/items.rs b/src/items.rs index 2547e8f5dd5..958dbb20df0 100644 --- a/src/items.rs +++ b/src/items.rs @@ -211,10 +211,8 @@ impl<'a> FmtVisitor<'a> { let ret_str = fd.output.rewrite(&context, self.config.max_width - indent, indent).unwrap(); // Args. - let (one_line_budget, multi_line_budget, mut arg_indent) = self.compute_budgets_for_args(&result, - indent, - ret_str.len(), - newline_brace); + let (one_line_budget, multi_line_budget, mut arg_indent) = + self.compute_budgets_for_args(&result, indent, ret_str.len(), newline_brace); debug!("rewrite_fn: one_line_budget: {}, multi_line_budget: {}, arg_indent: {}", one_line_budget, multi_line_budget, arg_indent); @@ -239,7 +237,10 @@ impl<'a> FmtVisitor<'a> { } // A conservative estimation, to goal is to be over all parens in generics - let args_start = generics.ty_params.last().map(|tp| end_typaram(tp)).unwrap_or(span.lo); + let args_start = generics.ty_params + .last() + .map(|tp| end_typaram(tp)) + .unwrap_or(span.lo); let args_span = codemap::mk_sp(span_after(codemap::mk_sp(args_start, span.hi), "(", self.codemap), diff --git a/src/utils.rs b/src/utils.rs index cb1dd718375..973f0fa56ab 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -211,8 +211,7 @@ pub fn wrap_str>(s: S, max_width: usize, width: usize, offset: usi impl Rewrite for String { fn rewrite(&self, context: &RewriteContext, width: usize, offset: usize) -> Option { - // FIXME: unnecessary clone - wrap_str(self.clone(), context.config.max_width, width, offset) + wrap_str(self, context.config.max_width, width, offset).map(ToOwned::to_owned) } } @@ -245,13 +244,13 @@ pub fn binary_search(mut lo: usize, mut hi: usize, callback: C) -> Option< #[test] fn bin_search_test() { let closure = |i| { - match i { - 4 => Ok(()), - j if j > 4 => Err(Ordering::Less), - j if j < 4 => Err(Ordering::Greater), - _ => unreachable!(), - } - }; + match i { + 4 => Ok(()), + j if j > 4 => Err(Ordering::Less), + j if j < 4 => Err(Ordering::Greater), + _ => unreachable!(), + } + }; assert_eq!(Some(()), binary_search(1, 10, &closure)); assert_eq!(None, binary_search(1, 3, &closure)); diff --git a/tests/source/chains-no-overflow.rs b/tests/source/chains-no-overflow.rs index fa2c66524fc..b94ca21b258 100644 --- a/tests/source/chains-no-overflow.rs +++ b/tests/source/chains-no-overflow.rs @@ -21,9 +21,8 @@ fn main() { { SCRIPT_TASK_ROOT .with(|root| { - // Another case of write_list failing us. - *root.borrow_mut() = Some(&script_task); - }); + *root.borrow_mut() = Some(&script_task); + }); }); let suuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuum = xxxxxxx diff --git a/tests/source/chains.rs b/tests/source/chains.rs index d2f11f1dcbe..f53afaa0c28 100644 --- a/tests/source/chains.rs +++ b/tests/source/chains.rs @@ -1,7 +1,7 @@ // Test chain formatting. fn main() { - // Don't put chains on a single list if it wasn't so in source. + // Don't put chains on a single line if it wasn't so in source. let a = b .c .d.1 .foo(|x| x + 1); @@ -11,6 +11,8 @@ fn main() { bbbbbbbbbbbbbbbbbbb.ccccccccccccccccccccccccccccccccccccc.ddddddddddddddddddddddddddd.eeeeeeee(); + // Test case where first chain element isn't a path, but is shorter than + // the size of a tab. x() .y(|| match cond() { true => (), false => () }); diff --git a/tests/source/string-lit.rs b/tests/source/string-lit.rs index e95aaae75e0..35d8ec072c2 100644 --- a/tests/source/string-lit.rs +++ b/tests/source/string-lit.rs @@ -30,5 +30,5 @@ formatting"#; let unicode3 = "中华Việt Nam"; let unicode4 = "☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃"; - "stuff" + "stuffin'" } diff --git a/tests/system.rs b/tests/system.rs index d0b6ae78faa..9086697978e 100644 --- a/tests/system.rs +++ b/tests/system.rs @@ -26,9 +26,9 @@ use rustfmt::rustfmt_diff::*; static DIFF_CONTEXT_SIZE: usize = 3; fn get_path_string(dir_entry: io::Result) -> String { - let path = dir_entry.ok().expect("Couldn\'t get DirEntry.").path(); + let path = dir_entry.ok().expect("Couldn't get DirEntry.").path(); - path.to_str().expect("Couldn\'t stringify path.").to_owned() + path.to_str().expect("Couldn't stringify path.").to_owned() } // Integration tests. The files in the tests/source are formatted and compared @@ -40,7 +40,7 @@ fn get_path_string(dir_entry: io::Result) -> String { #[test] fn system_tests() { // Get all files in the tests/source directory - let files = fs::read_dir("tests/source").ok().expect("Couldn\'t read source dir."); + let files = fs::read_dir("tests/source").ok().expect("Couldn't read source dir."); // turn a DirEntry into a String that represents the relative path to the file let files = files.map(get_path_string); @@ -56,9 +56,9 @@ fn system_tests() { #[test] fn idempotence_tests() { // Get all files in the tests/target directory - let files = fs::read_dir("tests/target").ok().expect("Couldn\'t read target dir."); - let files = files.chain(fs::read_dir("tests").ok().expect("Couldn\'t read tests dir.")); - let files = files.chain(fs::read_dir("src/bin").ok().expect("Couldn\'t read src dir.")); + let files = fs::read_dir("tests/target").ok().expect("Couldn't read target dir."); + let files = files.chain(fs::read_dir("tests").ok().expect("Couldn't read tests dir.")); + let files = files.chain(fs::read_dir("src/bin").ok().expect("Couldn't read src dir.")); // turn a DirEntry into a String that represents the relative path to the file let files = files.map(get_path_string); // hack because there's no `IntoIterator` impl for `[T; N]` @@ -139,9 +139,9 @@ fn get_config(config_file: Option<&str>) -> Box { let mut def_config_file = fs::File::open(config_file_name) .ok() - .expect("Couldn\'t open config."); + .expect("Couldn't open config."); let mut def_config = String::new(); - def_config_file.read_to_string(&mut def_config).ok().expect("Couldn\'t read config."); + def_config_file.read_to_string(&mut def_config).ok().expect("Couldn't read config."); Box::new(Config::from_toml(&def_config)) } @@ -151,7 +151,7 @@ fn get_config(config_file: Option<&str>) -> Box { fn read_significant_comments(file_name: &str) -> HashMap { let file = fs::File::open(file_name) .ok() - .expect(&format!("Couldn\'t read file {}.", file_name)); + .expect(&format!("Couldn't read file {}.", file_name)); let reader = BufReader::new(file); let pattern = r"^\s*//\s*rustfmt-([^:]+):\s*(\S+)"; let regex = regex::Regex::new(&pattern).ok().expect("Failed creating pattern 1."); @@ -166,8 +166,8 @@ fn read_significant_comments(file_name: &str) -> HashMap { .take_while(|line| line_regex.is_match(&line)) .filter_map(|line| { regex.captures_iter(&line).next().map(|capture| { - (capture.at(1).expect("Couldn\'t unwrap capture.").to_owned(), - capture.at(2).expect("Couldn\'t unwrap capture.").to_owned()) + (capture.at(1).expect("Couldn't unwrap capture.").to_owned(), + capture.at(2).expect("Couldn't unwrap capture.").to_owned()) }) }) .collect() @@ -185,7 +185,7 @@ fn handle_result(result: HashMap) { // If file is in tests/source, compare to file with same name in tests/target. let target = get_target(&file_name, sig_comments.get("target").map(|x| &(*x)[..])); - let mut f = fs::File::open(&target).ok().expect("Couldn\'t open target."); + let mut f = fs::File::open(&target).ok().expect("Couldn't open target."); let mut text = String::new(); // TODO: speedup by running through bytes iterator diff --git a/tests/target/chains-no-overflow.rs b/tests/target/chains-no-overflow.rs index b4fdb9f99ce..9b1f244637d 100644 --- a/tests/target/chains-no-overflow.rs +++ b/tests/target/chains-no-overflow.rs @@ -27,8 +27,8 @@ fn main() { fffffffffffffffffffffffffffffffffff(a, { SCRIPT_TASK_ROOT.with(|root| { - // Another case of write_list failing us. - *root.borrow_mut() = Some(&script_task); + *root.borrow_mut() = + Some(&script_task); }); }); diff --git a/tests/target/chains.rs b/tests/target/chains.rs index e49233e22a2..590f0a5b156 100644 --- a/tests/target/chains.rs +++ b/tests/target/chains.rs @@ -1,7 +1,7 @@ // Test chain formatting. fn main() { - // Don't put chains on a single list if it wasn't so in source. + // Don't put chains on a single line if it wasn't so in source. let a = b.c .d .1 @@ -13,6 +13,8 @@ fn main() { .ddddddddddddddddddddddddddd .eeeeeeee(); + // Test case where first chain element isn't a path, but is shorter than + // the size of a tab. x().y(|| { match cond() { true => (), diff --git a/tests/target/closure.rs b/tests/target/closure.rs index ec095ad8fcc..b42296487be 100644 --- a/tests/target/closure.rs +++ b/tests/target/closure.rs @@ -39,8 +39,8 @@ fn main() { let empty = |arg| {}; let simple = |arg| { /* TODO(#27): comment formatting */ - foo(arg) - }; + foo(arg) + }; let test = || { do_something(); @@ -62,8 +62,8 @@ fn main() { let closure_with_return_type = |aaaaaaaaaaaaaaaaaaaaaaarg1, aaaaaaaaaaaaaaaaaaaaaaarg2| -> Strong { - "sup".to_owned() - }; + "sup".to_owned() + }; |arg1, arg2, _, _, arg3, arg4| { let temp = arg4 + arg3; diff --git a/tests/target/string-lit.rs b/tests/target/string-lit.rs index 21cdc199d6e..36f8f6a48f9 100644 --- a/tests/target/string-lit.rs +++ b/tests/target/string-lit.rs @@ -36,5 +36,5 @@ formatting"#; let unicode4 = "☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃\ ☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃☃"; - "stuff" + "stuffin'" }