diff --git a/src/attr.rs b/src/attr.rs index b1efaa21f27..fe0dea02fdb 100644 --- a/src/attr.rs +++ b/src/attr.rs @@ -122,6 +122,7 @@ fn format_derive( context.snippet_provider.span_after(attr.span, "("), attr.span.hi(), false, + context.config.version(), ); Some(items) diff --git a/src/closures.rs b/src/closures.rs index 88a6bebb68c..923661976fe 100644 --- a/src/closures.rs +++ b/src/closures.rs @@ -283,6 +283,7 @@ fn rewrite_closure_fn_decl( context.snippet_provider.span_after(span, "|"), body.span.lo(), false, + context.config.version(), ); let item_vec = param_items.collect::>(); // 1 = space between parameters and return type. diff --git a/src/expr.rs b/src/expr.rs index c9d704765c2..9241c808a9b 100644 --- a/src/expr.rs +++ b/src/expr.rs @@ -1623,6 +1623,7 @@ fn rewrite_struct_lit<'a>( body_lo, span.hi(), false, + context.config.version(), ); let item_vec = items.collect::>(); @@ -1773,6 +1774,7 @@ fn rewrite_tuple_in_visual_indent_style<'a, T: 'a + IntoOverflowableItem<'a>>( list_lo, span.hi() - BytePos(1), false, + context.config.version(), ); let item_vec: Vec<_> = items.collect(); let tactic = definitive_tactic( diff --git a/src/imports.rs b/src/imports.rs index 140d8953abc..e9eb3364217 100644 --- a/src/imports.rs +++ b/src/imports.rs @@ -472,6 +472,7 @@ impl UseTree { context.snippet_provider.span_after(a.span, "{"), a.span.hi(), false, + context.config.version(), ); // in case of a global path and the nested list starts at the root, diff --git a/src/items.rs b/src/items.rs index 755a41f6bf0..5583bd9f5c4 100644 --- a/src/items.rs +++ b/src/items.rs @@ -381,8 +381,8 @@ impl<'a> FmtVisitor<'a> { return None; } - let res = Stmt::from_ast_node(block.stmts.first()?, true) - .rewrite(&self.get_context(), self.shape())?; + let res = + Stmt::from_ast_node(block.stmts.first()?, true).rewrite(&context, self.shape())?; let width = self.block_indent.width() + fn_str.len() + res.len() + 5; if !res.contains('\n') && width <= self.config.max_width() { @@ -441,7 +441,12 @@ impl<'a> FmtVisitor<'a> { self.last_pos = body_start; - match self.format_variant_list(enum_def, body_start, span.hi()) { + match self.format_variant_list( + enum_def, + body_start, + span.hi(), + self.get_context().config.version(), + ) { Some(ref s) if enum_def.variants.is_empty() => self.push_str(s), rw => { self.push_rewrite(mk_sp(body_start, span.hi()), rw); @@ -456,6 +461,7 @@ impl<'a> FmtVisitor<'a> { enum_def: &ast::EnumDef, body_lo: BytePos, body_hi: BytePos, + version: Version, ) -> Option { if enum_def.variants.is_empty() { let mut buffer = String::with_capacity(128); @@ -510,6 +516,7 @@ impl<'a> FmtVisitor<'a> { body_lo, body_hi, false, + version, ) .collect() }; @@ -2599,6 +2606,7 @@ fn rewrite_params( span.lo(), span.hi(), false, + context.config.version(), ) .collect(); @@ -2868,6 +2876,7 @@ fn rewrite_bounds_on_where_clause( span_start, span_end, false, + context.config.version(), ); let comma_tactic = if where_clause_option.suppress_comma || force_single_line { SeparatorTactic::Never @@ -2947,6 +2956,7 @@ fn rewrite_where_clause( span_start, span_end, false, + context.config.version(), ); let item_vec = items.collect::>(); // FIXME: we don't need to collect here diff --git a/src/lists.rs b/src/lists.rs index a878e6cf9b2..26c8f9a51d6 100644 --- a/src/lists.rs +++ b/src/lists.rs @@ -7,7 +7,7 @@ use rustc_span::BytePos; use crate::comment::{find_comment_end, rewrite_comment, FindUncommented}; use crate::config::lists::*; -use crate::config::{Config, IndentStyle}; +use crate::config::{Config, IndentStyle, Version}; use crate::rewrite::RewriteContext; use crate::shape::{Indent, Shape}; use crate::utils::{ @@ -570,6 +570,7 @@ where terminator: &'a str, separator: &'a str, leave_last: bool, + version: Version, } pub(crate) fn extract_pre_comment(pre_snippet: &str) -> (Option, ListItemCommentStyle) { @@ -612,11 +613,25 @@ pub(crate) fn extract_post_comment( comment_end: usize, separator: &str, is_last: bool, + version: Version, ) -> Option { let white_space: &[_] = &[' ', '\t']; // Cleanup post-comment: strip separators and whitespace. - let post_snippet = post_snippet[..comment_end].trim(); + let post_snippet = if version == Version::One { + post_snippet[..comment_end].trim() + } else { + // If trimmed string starts with comment - preserve leading new-line. + let post_snippet_start_trimmed = post_snippet[..comment_end].trim_start(); + if post_snippet_start_trimmed.starts_with("//") + || post_snippet_start_trimmed.starts_with("/*") + { + post_snippet[..comment_end].trim_matches(white_space) + } else { + post_snippet_start_trimmed + } + .trim_end() + }; let last_inline_comment_ends_with_separator = if is_last { if let Some(line) = post_snippet.lines().last() { @@ -767,8 +782,13 @@ where let comment_end = get_comment_end(post_snippet, self.separator, self.terminator, is_last); let new_lines = has_extra_newline(post_snippet, comment_end); - let post_comment = - extract_post_comment(post_snippet, comment_end, self.separator, is_last); + let post_comment = extract_post_comment( + post_snippet, + comment_end, + self.separator, + is_last, + self.version, + ); self.prev_span_end = (self.get_hi)(&item) + BytePos(comment_end as u32); @@ -800,6 +820,7 @@ pub(crate) fn itemize_list<'a, T, I, F1, F2, F3>( prev_span_end: BytePos, next_span_start: BytePos, leave_last: bool, + version: Version, ) -> ListItems<'a, I, F1, F2, F3> where I: Iterator, @@ -818,6 +839,7 @@ where terminator, separator, leave_last, + version, } } diff --git a/src/macros.rs b/src/macros.rs index 1bcb7774c94..a5741bb4f2c 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -438,6 +438,7 @@ pub(crate) fn rewrite_macro_def( context.snippet_provider.span_after(span, "{"), span.hi(), false, + context.config.version(), ) .collect::>(); diff --git a/src/matches.rs b/src/matches.rs index 85d9c5d2b9b..35710786f61 100644 --- a/src/matches.rs +++ b/src/matches.rs @@ -204,6 +204,7 @@ fn rewrite_match_arms( open_brace_pos, span.hi(), false, + context.config.version(), ); let arms_vec: Vec<_> = items.collect(); // We will add/remove commas inside `arm.rewrite()`, and hence no separator here. diff --git a/src/overflow.rs b/src/overflow.rs index 6bf8cd0c70b..bd781d8f877 100644 --- a/src/overflow.rs +++ b/src/overflow.rs @@ -587,7 +587,7 @@ impl<'a> Context<'a> { tactic } - fn rewrite_items(&self) -> Option<(bool, String)> { + fn rewrite_items(&self, version: Version) -> Option<(bool, String)> { let span = self.items_span(); let items = itemize_list( self.context.snippet_provider, @@ -600,6 +600,7 @@ impl<'a> Context<'a> { span.lo(), span.hi(), true, + version, ); let mut list_items: Vec<_> = items.collect(); @@ -682,7 +683,7 @@ impl<'a> Context<'a> { } fn rewrite(&self, shape: Shape) -> Option { - let (extendable, items_str) = self.rewrite_items()?; + let (extendable, items_str) = self.rewrite_items(self.context.config.version())?; // If we are using visual indent style and failed to format, retry with block indent. if !self.context.use_block_indent() diff --git a/src/patterns.rs b/src/patterns.rs index 9b74b35f314..792e83cc161 100644 --- a/src/patterns.rs +++ b/src/patterns.rs @@ -308,6 +308,7 @@ fn rewrite_struct_pat( context.snippet_provider.span_after(span, "{"), span.hi(), false, + context.config.version(), ); let item_vec = items.collect::>(); @@ -516,6 +517,7 @@ fn count_wildcard_suffix_len( context.snippet_provider.span_after(span, "("), span.hi() - BytePos(1), false, + context.config.version(), ) .collect(); diff --git a/src/reorder.rs b/src/reorder.rs index 9e4a668aa49..8768d1a528f 100644 --- a/src/reorder.rs +++ b/src/reorder.rs @@ -103,6 +103,7 @@ fn rewrite_reorderable_or_regroupable_items( span.lo(), span.hi(), false, + context.config.version(), ); for (item, list_item) in normalized_items.iter_mut().zip(list_items) { item.list_item = Some(list_item.clone()); @@ -155,6 +156,7 @@ fn rewrite_reorderable_or_regroupable_items( span.lo(), span.hi(), false, + context.config.version(), ); let mut item_pair_vec: Vec<_> = list_items.zip(reorderable_items.iter()).collect(); diff --git a/src/types.rs b/src/types.rs index 25ad587ba85..3c6d7bcd7e0 100644 --- a/src/types.rs +++ b/src/types.rs @@ -351,6 +351,7 @@ where list_lo, span.hi(), false, + context.config.version(), ); let item_vec: Vec<_> = items.collect(); diff --git a/src/vertical.rs b/src/vertical.rs index a06bc995aa5..15422b7a279 100644 --- a/src/vertical.rs +++ b/src/vertical.rs @@ -233,6 +233,7 @@ fn rewrite_aligned_items_inner( span.lo(), span.hi(), false, + context.config.version(), ) .collect::>(); diff --git a/tests/source/issue-4654.rs b/tests/source/issue-4654.rs new file mode 100644 index 00000000000..269f467beda --- /dev/null +++ b/tests/source/issue-4654.rs @@ -0,0 +1,129 @@ +// rustfmt-version: Two + +// Struct comments that start in new line + +// No trailing comma + +struct Foo { +bar: () +// Comment +} + +struct Bar { +baz: () +/* +Comment +*/ +} + +struct Baz( +() +// Comment +); + +fn main() { +let _ = Foo { +bar: () +/* +Comment +*/ +}; + +let _ = Bar { +baz: () +/* +Comment +*/ +}; + +let _ = Baz( +() +// Comment +); +} + +// With trailing comma + +struct Foo { +bar: (), +// Comment +} + +struct Bar { +baz: (), +/* +Comment +*/ +} + +struct Baz( +(), +// Comment +); + +fn main() { +let _ = Foo { +bar: (), +/* +Comment +*/ +}; + +let _ = Bar { +baz: (), +/* +Comment +*/ +}; + +let _ = Baz( +(), +// Comment +); +} + +// With new line before trailing comma + +struct Foo { +bar: () +, +// Comment +} + +struct Bar { +baz: () +, +/* +Comment +*/ +} + +struct Baz( +() +, +// Comment +); + +fn main() { +let _ = Foo { +bar: () +, +/* +Comment +*/ +}; + +let _ = Bar { +baz: () +, +/* +Comment +*/ +}; + +let _ = Baz( +() +, +// Comment +); +} diff --git a/tests/target/issue-4654.rs b/tests/target/issue-4654.rs new file mode 100644 index 00000000000..dd60554ba22 --- /dev/null +++ b/tests/target/issue-4654.rs @@ -0,0 +1,123 @@ +// rustfmt-version: Two + +// Struct comments that start in new line + +// No trailing comma + +struct Foo { + bar: (), + // Comment +} + +struct Bar { + baz: (), + /* + Comment + */ +} + +struct Baz( + (), + // Comment +); + +fn main() { + let _ = Foo { + bar: (), + /* + Comment + */ + }; + + let _ = Bar { + baz: (), + /* + Comment + */ + }; + + let _ = Baz( + (), + // Comment + ); +} + +// With trailing comma + +struct Foo { + bar: (), + // Comment +} + +struct Bar { + baz: (), + /* + Comment + */ +} + +struct Baz( + (), + // Comment +); + +fn main() { + let _ = Foo { + bar: (), + /* + Comment + */ + }; + + let _ = Bar { + baz: (), + /* + Comment + */ + }; + + let _ = Baz( + (), + // Comment + ); +} + +// With new line before trailing comma + +struct Foo { + bar: (), + // Comment +} + +struct Bar { + baz: (), + /* + Comment + */ +} + +struct Baz( + (), + // Comment +); + +fn main() { + let _ = Foo { + bar: (), + /* + Comment + */ + }; + + let _ = Bar { + baz: (), + /* + Comment + */ + }; + + let _ = Baz( + (), + // Comment + ); +}