diff --git a/Configurations.md b/Configurations.md index 5d8704ed779..c5efbe6a8a9 100644 --- a/Configurations.md +++ b/Configurations.md @@ -1251,6 +1251,40 @@ fn lorem() -> usize { See also: [`tab_spaces`](#tab_spaces). +## `fn_parameter_post_comment_alignment` + +Alignment of comments after function parameters + +- **Default value**: `SameIndent` +- **Possible values**: `SameIndent`, `SingleSpace` +- **Stable**: No + +#### `SameIndent` (default): + +Each comment has the same indentation. + +```rust +fn foo( + a: usize, // Cat + b: usize, // Dog + c: f32, // Bird +) { +} +``` + +#### `SingleSpace`: + +One space between the code and comment. + +```rust +fn foo( + a: usize, // Cat + b: usize, // Dog + c: f32, // Bird +) { +} +``` + ## `hex_literal_case` Control the case of the letters in hexadecimal literal values diff --git a/src/attr.rs b/src/attr.rs index ac9ce2e8796..21165a4b1cc 100644 --- a/src/attr.rs +++ b/src/attr.rs @@ -147,7 +147,12 @@ fn format_derive( .tactic(tactic) .trailing_separator(trailing_separator) .ends_with_newline(false); - let item_str = write_list(&all_items, &fmt).ok()?; + let item_str = write_list( + &all_items, + &fmt, + crate::config::PostCommentAlignment::SameIndent, + ) + .ok()?; debug!("item_str: '{}'", item_str); diff --git a/src/closures.rs b/src/closures.rs index 19cd0d9792c..e5dec828ae7 100644 --- a/src/closures.rs +++ b/src/closures.rs @@ -338,7 +338,11 @@ fn rewrite_closure_fn_decl( let fmt = ListFormatting::new(param_shape, context.config) .tactic(tactic) .preserve_newline(true); - let list_str = write_list(&item_vec, &fmt)?; + let list_str = write_list( + &item_vec, + &fmt, + crate::config::PostCommentAlignment::SameIndent, + )?; let mut prefix = format!("{binder}{const_}{immovable}{coro}{capture_str}|{list_str}|"); if !ret_str.is_empty() { diff --git a/src/config/mod.rs b/src/config/mod.rs index 8abb7439257..f5aae819573 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -78,6 +78,8 @@ create_config! { "Format the bodies of declarative macro definitions"; skip_macro_invocations: SkipMacroInvocations, false, "Skip formatting the bodies of macros invoked with the following names."; + fn_parameter_post_comment_alignment: FnParameterPostCommentAlignmentConfig, false, + "Alignment of comments after function parameters"; hex_literal_case: HexLiteralCaseConfig, false, "Format hexadecimal integer literals"; float_literal_trailing_zero: FloatLiteralTrailingZeroConfig, false, "Add or remove trailing zero in floating-point literals"; @@ -779,6 +781,7 @@ format_strings = false format_macro_matchers = false format_macro_bodies = true skip_macro_invocations = [] +fn_parameter_post_comment_alignment = "SameIndent" hex_literal_case = "Preserve" float_literal_trailing_zero = "Preserve" empty_item_single_line = true @@ -871,6 +874,7 @@ format_strings = false format_macro_matchers = false format_macro_bodies = true skip_macro_invocations = [] +fn_parameter_post_comment_alignment = "SameIndent" hex_literal_case = "Preserve" float_literal_trailing_zero = "Preserve" empty_item_single_line = true diff --git a/src/config/options.rs b/src/config/options.rs index 00f9c3f7ec1..5e3d1839d9a 100644 --- a/src/config/options.rs +++ b/src/config/options.rs @@ -135,6 +135,15 @@ pub enum ImportGranularity { One, } +/// Controls how rustfmt should align post comments. +#[config_type] +pub enum PostCommentAlignment { + /// List each comment with the same indentation from the previous. + SameIndent, + /// Insert one space between the code and comment. + SingleSpace, +} + /// Controls how rustfmt should handle case in hexadecimal literals. #[config_type] pub enum HexLiteralCase { @@ -627,6 +636,8 @@ config_option_with_style_edition_default!( FormatMacroMatchers, bool, _ => false; FormatMacroBodies, bool, _ => true; SkipMacroInvocations, MacroSelectors, _ => MacroSelectors::default(); + FnParameterPostCommentAlignmentConfig, PostCommentAlignment, _ => + PostCommentAlignment::SameIndent; HexLiteralCaseConfig, HexLiteralCase, _ => HexLiteralCase::Preserve; FloatLiteralTrailingZeroConfig, FloatLiteralTrailingZero, _ => FloatLiteralTrailingZero::Preserve; diff --git a/src/expr.rs b/src/expr.rs index b79137c4442..0d324cfea42 100644 --- a/src/expr.rs +++ b/src/expr.rs @@ -1869,7 +1869,11 @@ fn rewrite_struct_lit<'a>( force_no_trailing_comma || has_base_or_rest || !context.use_block_indent(), ); - write_list(&item_vec, &fmt)? + write_list( + &item_vec, + &fmt, + crate::config::PostCommentAlignment::SameIndent, + )? }; let fields_str = @@ -2016,7 +2020,11 @@ fn rewrite_tuple_in_visual_indent_style<'a, T: 'a + IntoOverflowableItem<'a>>( let fmt = ListFormatting::new(nested_shape, context.config) .tactic(tactic) .ends_with_newline(false); - let list_str = write_list(&item_vec, &fmt)?; + let list_str = write_list( + &item_vec, + &fmt, + crate::config::PostCommentAlignment::SameIndent, + )?; Ok(format!("({list_str})")) } diff --git a/src/imports.rs b/src/imports.rs index 2f26791639a..577e050f28c 100644 --- a/src/imports.rs +++ b/src/imports.rs @@ -1066,7 +1066,11 @@ fn rewrite_nested_use_tree( .preserve_newline(true) .nested(has_nested_list); - let list_str = write_list(&list_items, &fmt)?; + let list_str = write_list( + &list_items, + &fmt, + crate::config::PostCommentAlignment::SameIndent, + )?; let result = if (list_str.contains('\n') || list_str.len() > remaining_width diff --git a/src/items.rs b/src/items.rs index a2c0e8e0f50..760ca221ec3 100644 --- a/src/items.rs +++ b/src/items.rs @@ -652,7 +652,12 @@ impl<'a> FmtVisitor<'a> { .trailing_separator(self.config.trailing_comma()) .preserve_newline(true); - let list = write_list(&items, &fmt).ok()?; + let list = write_list( + &items, + &fmt, + crate::config::PostCommentAlignment::SameIndent, + ) + .ok()?; result.push_str(&list); result.push_str(&original_offset.to_string_with_newline(self.config)); result.push('}'); @@ -2899,7 +2904,11 @@ fn rewrite_params( .trailing_separator(trailing_separator) .ends_with_newline(tactic.ends_with_newline(context.config.indent_style())) .preserve_newline(true); - write_list(¶m_items, &fmt) + write_list( + ¶m_items, + &fmt, + context.config.fn_parameter_post_comment_alignment(), + ) } fn compute_budgets_for_params( @@ -3161,7 +3170,11 @@ fn rewrite_bounds_on_where_clause( .tactic(shape_tactic) .trailing_separator(comma_tactic) .preserve_newline(preserve_newline); - write_list(&items.collect::>(), &fmt) + write_list( + &items.collect::>(), + &fmt, + crate::config::PostCommentAlignment::SameIndent, + ) } fn rewrite_where_clause( @@ -3242,7 +3255,11 @@ fn rewrite_where_clause( .trailing_separator(comma_tactic) .ends_with_newline(tactic.ends_with_newline(context.config.indent_style())) .preserve_newline(true); - let preds_str = write_list(&item_vec, &fmt)?; + let preds_str = write_list( + &item_vec, + &fmt, + crate::config::PostCommentAlignment::SameIndent, + )?; let end_length = if terminator == "{" { // If the brace is on the next line we don't need to count it otherwise it needs two diff --git a/src/lists.rs b/src/lists.rs index 9d811e5d9b5..ca6b720cdac 100644 --- a/src/lists.rs +++ b/src/lists.rs @@ -6,8 +6,8 @@ use std::iter::Peekable; use rustc_span::{BytePos, Span}; use crate::comment::{FindUncommented, find_comment_end, rewrite_comment}; -use crate::config::lists::*; use crate::config::{Config, IndentStyle}; +use crate::config::{PostCommentAlignment, lists::*}; use crate::rewrite::{ExceedsMaxWidthError, RewriteContext, RewriteError, RewriteResult}; use crate::shape::{Indent, Shape}; use crate::utils::{ @@ -261,7 +261,11 @@ where } // Format a list of commented items into a string. -pub(crate) fn write_list(items: I, formatting: &ListFormatting<'_>) -> RewriteResult +pub(crate) fn write_list( + items: I, + formatting: &ListFormatting<'_>, + post_comment_alignment_config: PostCommentAlignment, +) -> RewriteResult where I: IntoIterator + Clone, T: AsRef, @@ -467,34 +471,45 @@ where let mut formatted_comment = rewrite_post_comment(&mut item_max_width)?; if !starts_with_newline(comment) { - if formatting.align_comments { - let mut comment_alignment = - post_comment_alignment(item_max_width, unicode_str_width(inner_item)); - 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)?; - comment_alignment = - post_comment_alignment(item_max_width, unicode_str_width(inner_item)); + match post_comment_alignment_config { + PostCommentAlignment::SameIndent => { + if formatting.align_comments { + let mut comment_alignment = post_comment_alignment( + item_max_width, + unicode_str_width(inner_item), + ); + 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)?; + comment_alignment = post_comment_alignment( + item_max_width, + unicode_str_width(inner_item), + ); + } + for _ in 0..=comment_alignment { + result.push(' '); + } + } + // An additional space for the missing trailing separator (or + // if we skipped alignment above). + if !formatting.align_comments + || (last + && item_max_width.is_some() + && !separate + && !formatting.separator.is_empty()) + { + result.push(' '); + } } - for _ in 0..=comment_alignment { + PostCommentAlignment::SingleSpace => { result.push(' '); } } - // An additional space for the missing trailing separator (or - // if we skipped alignment above). - if !formatting.align_comments - || (last - && item_max_width.is_some() - && !separate - && !formatting.separator.is_empty()) - { - result.push(' '); - } } else { result.push('\n'); result.push_str(indent_str); diff --git a/src/macros.rs b/src/macros.rs index 2d56021069c..3699bf2f4de 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -497,7 +497,11 @@ pub(crate) fn rewrite_macro_def( result += &arm_shape.indent.to_string_with_newline(context.config); } - match write_list(&branch_items, &fmt) { + match write_list( + &branch_items, + &fmt, + crate::config::PostCommentAlignment::SameIndent, + ) { Ok(ref s) => result += s, Err(_) => return snippet, } diff --git a/src/matches.rs b/src/matches.rs index 4741abbe465..12adc239e78 100644 --- a/src/matches.rs +++ b/src/matches.rs @@ -242,7 +242,11 @@ fn rewrite_match_arms( .separator("") .preserve_newline(true); - write_list(&arms_vec, &fmt) + write_list( + &arms_vec, + &fmt, + crate::config::PostCommentAlignment::SameIndent, + ) } fn rewrite_match_arm( diff --git a/src/overflow.rs b/src/overflow.rs index 4230c89b57b..6c327f68c67 100644 --- a/src/overflow.rs +++ b/src/overflow.rs @@ -663,8 +663,12 @@ impl<'a> Context<'a> { .trailing_separator(trailing_separator) .ends_with_newline(ends_with_newline); - write_list(&list_items, &fmt) - .map(|items_str| (tactic == DefinitiveListTactic::Horizontal, items_str)) + write_list( + &list_items, + &fmt, + crate::config::PostCommentAlignment::SameIndent, + ) + .map(|items_str| (tactic == DefinitiveListTactic::Horizontal, items_str)) } fn wrap_items(&self, items_str: &str, shape: Shape, is_extendable: bool) -> String { diff --git a/src/patterns.rs b/src/patterns.rs index df2a8dc5c6f..75c53235358 100644 --- a/src/patterns.rs +++ b/src/patterns.rs @@ -129,7 +129,11 @@ impl Rewrite for Pat { .separator(" |") .separator_place(context.config.binop_separator()) .ends_with_newline(false); - write_list(&items, &fmt) + write_list( + &items, + &fmt, + crate::config::PostCommentAlignment::SameIndent, + ) } PatKind::Box(ref pat) => rewrite_unary_prefix(context, "box ", &**pat, shape), PatKind::Ident(BindingMode(by_ref, mutability), ident, ref sub_pat) => { @@ -452,7 +456,11 @@ fn rewrite_struct_pat( let nested_shape = shape_for_tactic(tactic, h_shape, v_shape); let fmt = struct_lit_formatting(nested_shape, tactic, context, false); - let mut fields_str = write_list(&item_vec, &fmt)?; + let mut fields_str = write_list( + &item_vec, + &fmt, + crate::config::PostCommentAlignment::SameIndent, + )?; let one_line_width = h_shape.map_or(0, |shape| shape.width); let has_trailing_comma = fmt.needs_trailing_separator(); diff --git a/src/reorder.rs b/src/reorder.rs index 6ef6e0bc969..8bbff59fc3e 100644 --- a/src/reorder.rs +++ b/src/reorder.rs @@ -76,7 +76,11 @@ fn wrap_reorderable_items( let fmt = ListFormatting::new(shape, context.config) .separator("") .align_comments(false); - write_list(list_items, &fmt) + write_list( + list_items, + &fmt, + crate::config::PostCommentAlignment::SameIndent, + ) } fn rewrite_reorderable_item( diff --git a/src/types.rs b/src/types.rs index 94ed42c6ea5..30057f39217 100644 --- a/src/types.rs +++ b/src/types.rs @@ -405,7 +405,14 @@ where .trailing_separator(trailing_separator) .ends_with_newline(tactic.ends_with_newline(context.config.indent_style())) .preserve_newline(true); - (write_list(&item_vec, &fmt)?, tactic) + ( + write_list( + &item_vec, + &fmt, + crate::config::PostCommentAlignment::SameIndent, + )?, + tactic, + ) }; let args = if tactic == DefinitiveListTactic::Horizontal diff --git a/src/vertical.rs b/src/vertical.rs index 21e34d29710..5148a43df44 100644 --- a/src/vertical.rs +++ b/src/vertical.rs @@ -266,7 +266,12 @@ fn rewrite_aligned_items_inner( .tactic(tactic) .trailing_separator(separator_tactic) .preserve_newline(true); - write_list(&items, &fmt).ok() + write_list( + &items, + &fmt, + crate::config::PostCommentAlignment::SameIndent, + ) + .ok() } /// Returns the index in `fields` up to which a field belongs to the current group. diff --git a/tests/source/issue-4108/same_indent_fn_parameter_post_comment_alignment.rs b/tests/source/issue-4108/same_indent_fn_parameter_post_comment_alignment.rs new file mode 100644 index 00000000000..b0758caaef3 --- /dev/null +++ b/tests/source/issue-4108/same_indent_fn_parameter_post_comment_alignment.rs @@ -0,0 +1,15 @@ +// rustfmt-fn_parameter_post_comment_alignment: SameIndent + +fn foo( + a: usize, // Chirp + b: usize, // Bark + c: f32, // Meow +) { +} + +fn bar( + a: usize,/* Chirp */ + b: usize, // Bark + c: f32, /* Meow */ +) { +} diff --git a/tests/source/issue-4108/single_space_fn_parameter_post_comment_alignment.rs b/tests/source/issue-4108/single_space_fn_parameter_post_comment_alignment.rs new file mode 100644 index 00000000000..639c5432d5d --- /dev/null +++ b/tests/source/issue-4108/single_space_fn_parameter_post_comment_alignment.rs @@ -0,0 +1,22 @@ +// rustfmt-fn_parameter_post_comment_alignment: SingleSpace + +fn foo( + a: usize, // Chirp + b: usize, // Bark + c: f32, // Meow +) { +} + +fn bar( + a: usize,/* Chirp */ + b: usize, // Bark + c: f32, /* Meow */ +) { + // `fn_parameter_post_comment_alignment` should not + // affect post comments for match statements. + match 0 { + 0 => todo!(), // IIIS + 1 => todo!(), // ASD + _ => {} // Meep + } +} diff --git a/tests/target/issue-4108/same_indent_fn_parameter_post_comment_alignment.rs b/tests/target/issue-4108/same_indent_fn_parameter_post_comment_alignment.rs new file mode 100644 index 00000000000..a1d1cb3419f --- /dev/null +++ b/tests/target/issue-4108/same_indent_fn_parameter_post_comment_alignment.rs @@ -0,0 +1,15 @@ +// rustfmt-fn_parameter_post_comment_alignment: SameIndent + +fn foo( + a: usize, // Chirp + b: usize, // Bark + c: f32, // Meow +) { +} + +fn bar( + a: usize, /* Chirp */ + b: usize, // Bark + c: f32, /* Meow */ +) { +} diff --git a/tests/target/issue-4108/single_space_fn_parameter_post_comment_alignment.rs b/tests/target/issue-4108/single_space_fn_parameter_post_comment_alignment.rs new file mode 100644 index 00000000000..e6e95bcc07a --- /dev/null +++ b/tests/target/issue-4108/single_space_fn_parameter_post_comment_alignment.rs @@ -0,0 +1,22 @@ +// rustfmt-fn_parameter_post_comment_alignment: SingleSpace + +fn foo( + a: usize, // Chirp + b: usize, // Bark + c: f32, // Meow +) { +} + +fn bar( + a: usize, /* Chirp */ + b: usize, // Bark + c: f32, /* Meow */ +) { + // `fn_parameter_post_comment_alignment` should not + // affect post comments for match statements. + match 0 { + 0 => todo!(), // IIIS + 1 => todo!(), // ASD + _ => {} // Meep + } +}