diff --git a/src/comment.rs b/src/comment.rs index 439a7f6a05f..441bb858e2a 100644 --- a/src/comment.rs +++ b/src/comment.rs @@ -305,27 +305,42 @@ fn rewrite_comment_inner( line }) .map(|s| left_trim_comment_line(s, &style)) - .map(|line| { + .map(|(line, has_leading_whitespace)| { if orig.starts_with("/*") && line_breaks == 0 { - line.trim_left() + ( + line.trim_left(), + has_leading_whitespace || config.normalize_comments(), + ) } else { - line + (line, has_leading_whitespace || config.normalize_comments()) } }); - let mut result = opener.to_owned(); + let mut result = String::with_capacity(orig.len() * 2); + result.push_str(opener); let mut is_prev_line_multi_line = false; let mut inside_code_block = false; let comment_line_separator = format!("\n{}{}", indent_str, line_start); - for line in lines { + for (i, (line, has_leading_whitespace)) in lines.enumerate() { + let is_last = i == count_newlines(orig); if result == opener { + let force_leading_whitespace = opener == "/* " && count_newlines(orig) == 0; + if !has_leading_whitespace && !force_leading_whitespace && result.ends_with(' ') { + result.pop(); + } if line.is_empty() { continue; } } else if is_prev_line_multi_line && !line.is_empty() { result.push(' ') + } else if is_last && !closer.is_empty() && line.is_empty() { + result.push('\n'); + result.push_str(&indent_str); } else { result.push_str(&comment_line_separator); + if !has_leading_whitespace && result.ends_with(' ') { + result.pop(); + } } if line.starts_with("```") { @@ -381,7 +396,7 @@ fn rewrite_comment_inner( Shape::legacy(max_chars, fmt_indent) }; } else { - if line.is_empty() && result.ends_with(' ') { + if line.is_empty() && result.ends_with(' ') && !is_last { // Remove space if this is an empty comment or a doc comment. result.pop(); } @@ -473,32 +488,33 @@ fn light_rewrite_comment(orig: &str, offset: Indent, config: &Config) -> Option< } /// Trims comment characters and possibly a single space from the left of a string. -/// Does not trim all whitespace. -fn left_trim_comment_line<'a>(line: &'a str, style: &CommentStyle) -> &'a str { +/// 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("/*! ") || line.starts_with("/** ") { - &line[4..] + (&line[4..], true) } else if let CommentStyle::Custom(opener) = *style { if line.starts_with(opener) { - &line[opener.len()..] + (&line[opener.len()..], true) } else { - &line[opener.trim_right().len()..] + (&line[opener.trim_right().len()..], false) } } 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[3..], line.chars().nth(2).unwrap() == ' ') } else if line.starts_with("/*") || line.starts_with("* ") || line.starts_with("//") || line.starts_with("**") { - &line[2..] + (&line[2..], line.chars().nth(1).unwrap() == ' ') } else if line.starts_with('*') { - &line[1..] + (&line[1..], false) } else { - line + (line, line.starts_with(' ')) } } diff --git a/tests/target/enum.rs b/tests/target/enum.rs index 779c8b168a3..ac7c835f80a 100644 --- a/tests/target/enum.rs +++ b/tests/target/enum.rs @@ -58,7 +58,7 @@ enum X { } pub enum EnumWithAttributes { - // This is a pre comment + //This is a pre comment // AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA TupleVar(usize, usize, usize), /* AAAA AAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAA * AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA */ diff --git a/tests/target/issue-2123.rs b/tests/target/issue-2123.rs new file mode 100644 index 00000000000..5e9917b4023 --- /dev/null +++ b/tests/target/issue-2123.rs @@ -0,0 +1,6 @@ +// rustfmt-wrap_comments: true + +//hello +//world + +fn main() {} diff --git a/tests/target/structs.rs b/tests/target/structs.rs index 8015fc8eb2e..2b3647eb8e7 100644 --- a/tests/target/structs.rs +++ b/tests/target/structs.rs @@ -271,7 +271,7 @@ struct Foo { aaaaaaa: u32, /* multi * line * comment - * */ + */ b: u32, // hi do_not_push_this_comment1: u32, // comment1 diff --git a/tests/target/unions.rs b/tests/target/unions.rs index ed7b842a411..2394d9656e4 100644 --- a/tests/target/unions.rs +++ b/tests/target/unions.rs @@ -176,7 +176,7 @@ union Foo { aaaaaaa: u32, /* multi * line * comment - * */ + */ b: u32, // hi do_not_push_this_comment1: u32, // comment1