diff --git a/src/lists.rs b/src/lists.rs index 9d811e5d9b5..2ccf1ef7749 100644 --- a/src/lists.rs +++ b/src/lists.rs @@ -21,7 +21,11 @@ pub(crate) struct ListFormatting<'a> { separator: &'a str, trailing_separator: SeparatorTactic, separator_place: SeparatorPlace, + // The shape available to a list item, including any width reserved for its separator. shape: Shape, + // Overrides the item shape for pre-comments. The item shape may reserve space for a separator, + // which is not part of a preceding comment. + pre_comment_shape: Option, // Non-expressions, e.g., items, will have a new line at the end of the list. // Important for comment styles. ends_with_newline: bool, @@ -42,6 +46,7 @@ impl<'a> ListFormatting<'a> { trailing_separator: SeparatorTactic::Never, separator_place: SeparatorPlace::Back, shape, + pre_comment_shape: None, ends_with_newline: true, preserve_newline: false, nested: false, @@ -70,6 +75,11 @@ impl<'a> ListFormatting<'a> { self } + pub(crate) fn pre_comment_shape(mut self, pre_comment_shape: Shape) -> Self { + self.pre_comment_shape = Some(pre_comment_shape); + self + } + pub(crate) fn ends_with_newline(mut self, ends_with_newline: bool) -> Self { self.ends_with_newline = ends_with_newline; self @@ -366,8 +376,8 @@ where // Block style in non-vertical mode. let block_mode = tactic == DefinitiveListTactic::Horizontal; // Width restriction is only relevant in vertical mode. - let comment = - rewrite_comment(comment, block_mode, formatting.shape, formatting.config)?; + let comment_shape = formatting.pre_comment_shape.unwrap_or(formatting.shape); + let comment = rewrite_comment(comment, block_mode, comment_shape, formatting.config)?; result.push_str(&comment); if !inner_item.is_empty() { @@ -941,6 +951,7 @@ pub(crate) fn struct_lit_formatting<'a>( }, separator_place: SeparatorPlace::Back, shape, + pre_comment_shape: None, ends_with_newline, preserve_newline: true, nested: false, diff --git a/src/vertical.rs b/src/vertical.rs index fd9a4a7db6a..bf1718f7482 100644 --- a/src/vertical.rs +++ b/src/vertical.rs @@ -214,6 +214,7 @@ fn rewrite_aligned_items_inner( ) -> Option { // 1 = "," let item_shape = Shape::indented(offset, context.config).sub_width_opt(1)?; + let pre_comment_shape = Shape::indented(offset, context.config); let (mut field_prefix_max_width, field_prefix_min_width) = struct_field_prefix_max_min_width(context, fields, item_shape); let max_diff = field_prefix_max_width.saturating_sub(field_prefix_min_width); @@ -265,6 +266,7 @@ fn rewrite_aligned_items_inner( let fmt = ListFormatting::new(item_shape, context.config) .tactic(tactic) .trailing_separator(separator_tactic) + .pre_comment_shape(pre_comment_shape) .preserve_newline(true); write_list(&items, &fmt).ok() } diff --git a/tests/source/issue_6180.rs b/tests/source/issue_6180.rs new file mode 100644 index 00000000000..f8c33fe0d9b --- /dev/null +++ b/tests/source/issue_6180.rs @@ -0,0 +1,18 @@ +// rustfmt-wrap_comments: true +// rustfmt-comment_width: 100 + +pub struct Foo { + // This line has 99 characters ...............................................................9 + pub foo: u8, + + // This line has 100 characters ...............................................................9 + pub bar: u8, + + // This line has 101 characters ................................................................9 + pub baz: u8, +} + +pub mod foo { + // This line has 100 characters ...............................................................9 + pub fn foo() {} +} diff --git a/tests/target/configs/struct_field_align_threshold/20.rs b/tests/target/configs/struct_field_align_threshold/20.rs index 12a523e9d83..388513e085a 100644 --- a/tests/target/configs/struct_field_align_threshold/20.rs +++ b/tests/target/configs/struct_field_align_threshold/20.rs @@ -321,8 +321,8 @@ fn main() { A { // Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit - // amet ipsum mauris. Maecenas congue ligula ac quam viverra nec consectetur ante - // hendrerit. Donec et mollis dolor. + // amet ipsum mauris. Maecenas congue ligula ac quam viverra nec consectetur ante hendrerit. + // Donec et mollis dolor. first: item(), // Praesent et diam eget libero egestas mattis sit amet vitae augue. // Nam tincidunt congue enim, ut porta lorem lacinia consectetur. diff --git a/tests/target/issue_6180.rs b/tests/target/issue_6180.rs new file mode 100644 index 00000000000..4dd40882a66 --- /dev/null +++ b/tests/target/issue_6180.rs @@ -0,0 +1,19 @@ +// rustfmt-wrap_comments: true +// rustfmt-comment_width: 100 + +pub struct Foo { + // This line has 99 characters ...............................................................9 + pub foo: u8, + + // This line has 100 characters ...............................................................9 + pub bar: u8, + + // This line has 101 characters + // ................................................................9 + pub baz: u8, +} + +pub mod foo { + // This line has 100 characters ...............................................................9 + pub fn foo() {} +}