Repository: rust-lang/rustfmt (rust)

Issue:
Rename `fn_args_layout` config option
We previously (#3803) refactored the `arg` name to `param` internally within rustfmt  where appropriate to reflect the upstream changes (rust-lang/rust#62426), but did not change the public/external-facing [`fn_args_layout` config option](https://github.com/rust-lang/rustfmt/blob/master/Configurations.md#fn_args_layout) because that would have been a breaking change.

However, this config option is indeed used as part of the formatting of the parameters in a fn signature, not in the formatting of args in a fn call. As such this should also be renamed as part of the major version release (`fn_params_layout` seems  like a reasonable name)

@topecongiro I've added this to the 2.0 milestone per our previous discussion in https://github.com/rust-lang/rustfmt/pull/3803#issuecomment-533901176, but of course feel free to change that if you think we should defer it.

Below are the steps involved for anyone interested in working on this:
* Rename the configuration option and update the help text in `rustfmt-core/rustfmt-lib/src/config.rs`
https://github.com/rust-lang/rustfmt/blob/7194d529467cf7748bd0031ecf35ae8917f98992/rustfmt-core/rustfmt-lib/src/config.rs#L111-L112
    * make sure to update the corresponding test in that file too https://github.com/rust-lang/rustfmt/blob/master/rustfmt-core/rustfmt-lib/src/config.rs#L556
* Rename the corresponding test files/update config references under `rustfmt-core/rustfmt-lib/tests/{source,target}`
   * For example, rename [tests/source/fn_args_layout-vertical.rs](https://github.com/rust-lang/rustfmt/blob/master/rustfmt-core/rustfmt-lib/tests/source/fn_args_layout-vertical.rs)  (and the same for the matching file under `tests/target`)to `fn_params_layout-vertical.rs` and the inline config to be `// rustfmt-fn_params_layout: Vertical`
    * Same thing for [`tests/{source,target}/configs/fn_args_layout`]( https://github.com/rust-lang/rustfmt/tree/master/rustfmt-core/rustfmt-lib/tests/source/configs/fn_args_layout), rename the directory and update the inline config in the files with the new config option name
https://github.com/rust-lang/rustfmt/blob/7194d529467cf7748bd0031ecf35ae8917f98992/rustfmt-core/rustfmt-lib/tests/source/fn_args_layout-vertical.rs#L1-L2

* Rename/update the [corresponding section in Configurations.md](https://github.com/rust-lang/rustfmt/blob/master/Configurations.md#fn_args_layout)


Pull request:
Rename `fn_args_layout` -> `fn_params_layout`
`fn_args_layout` was renamed `fn_params_layout` to better communicate that it affects the layout of parameters in function signatures and not the layout of arguments in function calls.

Because the `fn_args_layout` is a stable option the renamed option is also stable, however users who set `fn_args_layout` will get a warning message letting them know that the option has been renamed.

Closes #4149

Patch:
diff --git a/Configurations.md b/Configurations.md
index 8b96b9d3..17eabd48 100644
--- a/Configurations.md
+++ b/Configurations.md
@@ -645,7 +645,8 @@ trailing whitespaces.
 
 ## `fn_args_layout`
 
-Control the layout of arguments in a function
+This option is deprecated and has been renamed to `fn_params_layout` to better communicate that
+it affects the layout of parameters in function signatures.
 
 - **Default value**: `"Tall"`
 - **Possible values**: `"Compressed"`, `"Tall"`, `"Vertical"`
@@ -753,6 +754,8 @@ trait Lorem {
 }
 ```
 
+See also [`fn_params_layout`](#fn_params_layout)
+
 ## `fn_call_width`
 
 Maximum width of the args of a function call before falling back to vertical formatting.
@@ -765,6 +768,117 @@ By default this option is set as a percentage of [`max_width`](#max_width) provi
 
 See also [`max_width`](#max_width) and [`use_small_heuristics`](#use_small_heuristics)
 
+## `fn_params_layout`
+
+Control the layout of parameters in function signatures.
+
+- **Default value**: `"Tall"`
+- **Possible values**: `"Compressed"`, `"Tall"`, `"Vertical"`
+- **Stable**: Yes
+
+#### `"Tall"` (default):
+
+```rust
+trait Lorem {
+    fn lorem(ipsum: Ipsum, dolor: Dolor, sit: Sit, amet: Amet);
+
+    fn lorem(ipsum: Ipsum, dolor: Dolor, sit: Sit, amet: Amet) {
+        // body
+    }
+
+    fn lorem(
+        ipsum: Ipsum,
+        dolor: Dolor,
+        sit: Sit,
+        amet: Amet,
+        consectetur: Consectetur,
+        adipiscing: Adipiscing,
+        elit: Elit,
+    );
+
+    fn lorem(
+        ipsum: Ipsum,
+        dolor: Dolor,
+        sit: Sit,
+        amet: Amet,
+        consectetur: Consectetur,
+        adipiscing: Adipiscing,
+        elit: Elit,
+    ) {
+        // body
+    }
+}
+```
+
+#### `"Compressed"`:
+
+```rust
+trait Lorem {
+    fn lorem(ipsum: Ipsum, dolor: Dolor, sit: Sit, amet: Amet);
+
+    fn lorem(ipsum: Ipsum, dolor: Dolor, sit: Sit, amet: Amet) {
+        // body
+    }
+
+    fn lorem(
+        ipsum: Ipsum, dolor: Dolor, sit: Sit, amet: Amet, consectetur: Consectetur,
+        adipiscing: Adipiscing, elit: Elit,
+    );
+
+    fn lorem(
+        ipsum: Ipsum, dolor: Dolor, sit: Sit, amet: Amet, consectetur: Consectetur,
+        adipiscing: Adipiscing, elit: Elit,
+    ) {
+        // body
+    }
+}
+```
+
+#### `"Vertical"`:
+
+```rust
+trait Lorem {
+    fn lorem(
+        ipsum: Ipsum,
+        dolor: Dolor,
+        sit: Sit,
+        amet: Amet,
+    );
+
+    fn lorem(
+        ipsum: Ipsum,
+        dolor: Dolor,
+        sit: Sit,
+        amet: Amet,
+    ) {
+        // body
+    }
+
+    fn lorem(
+        ipsum: Ipsum,
+        dolor: Dolor,
+        sit: Sit,
+        amet: Amet,
+        consectetur: Consectetur,
+        adipiscing: Adipiscing,
+        elit: Elit,
+    );
+
+    fn lorem(
+        ipsum: Ipsum,
+        dolor: Dolor,
+        sit: Sit,
+        amet: Amet,
+        consectetur: Consectetur,
+        adipiscing: Adipiscing,
+        elit: Elit,
+    ) {
+        // body
+    }
+}
+```
+
+
 ## `fn_single_line`
 
 Put single-expression functions on a single line
@@ -1014,6 +1128,62 @@ macro_rules! foo {
 
 See also [`format_macro_matchers`](#format_macro_matchers).
 
+## `skip_macro_invocations`
+
+Skip formatting the bodies of macro invocations with the following names.
+
+rustfmt will not format any macro invocation for macros with names set in this list.
+Including the special value "*" will prevent any macro invocations from being formatted.
+
+Note: This option does not have any impact on how rustfmt formats macro definitions.
+
+- **Default value**: `[]`
+- **Possible values**: a list of macro name idents, `["name_0", "name_1", ..., "*"]`
+- **Stable**: No (tracking issue: [#5346](https://github.com/rust-lang/rustfmt/issues/5346))
+
+#### `[]` (default):
+
+rustfmt will follow its standard approach to formatting macro invocations.
+
+No macro invocations will be skipped based on their name. More information about rustfmt's standard macro invocation formatting behavior can be found in [#5437](https://github.com/rust-lang/rustfmt/discussions/5437).
+
+```rust
+lorem!(
+    const _: u8 = 0;
+);
+
+ipsum!(
+    const _: u8 = 0;
+);
+```
+
+#### `["lorem"]`:
+
+The named macro invocations will be skipped.
+
+```rust
+lorem!(
+        const _: u8 = 0;
+);
+
+ipsum!(
+    const _: u8 = 0;
+);
+```
+
+#### `["*"]`:
+
+The special selector `*` will skip all macro invocations.
+
+```rust
+lorem!(
+        const _: u8 = 0;
+);
+
+ipsum!(
+        const _: u8 = 0;
+);
+```
 
 ## `format_strings`
 
diff --git a/src/config/config_type.rs b/src/config/config_type.rs
index 26d57a13..90a67e12 100644
--- a/src/config/config_type.rs
+++ b/src/config/config_type.rs
@@ -1,4 +1,5 @@
 use crate::config::file_lines::FileLines;
+use crate::config::macro_names::MacroSelectors;
 use crate::config::options::{IgnoreList, WidthHeuristics};
 
 /// Trait for types that can be used in `Config`.
@@ -46,6 +47,12 @@ impl ConfigType for FileLines {
     }
 }
 
+impl ConfigType for MacroSelectors {
+    fn doc_hint() -> String {
+        String::from("[<string>, ...]")
+    }
+}
+
 impl ConfigType for WidthHeuristics {
     fn doc_hint() -> String {
         String::new()
@@ -120,6 +127,7 @@ macro_rules! create_config {
                     | "array_width"
                     | "chain_width" => self.0.set_heuristics(),
                     "merge_imports" => self.0.set_merge_imports(),
+                    "fn_args_layout" => self.0.set_fn_args_layout(),
                     &_ => (),
                 }
             }
@@ -174,6 +182,7 @@ macro_rules! create_config {
                 self.set_heuristics();
                 self.set_ignore(dir);
                 self.set_merge_imports();
+                self.set_fn_args_layout();
                 self
             }
 
@@ -266,14 +275,21 @@ macro_rules! create_config {
                     | "array_width"
                     | "chain_width" => self.set_heuristics(),
                     "merge_imports" => self.set_merge_imports(),
+                    "fn_args_layout" => self.set_fn_args_layout(),
                     &_ => (),
                 }
             }
 
             #[allow(unreachable_pub)]
             pub fn is_hidden_option(name: &str) -> bool {
-                const HIDE_OPTIONS: [&str; 5] =
-                    ["verbose", "verbose_diff", "file_lines", "width_heuristics", "merge_imports"];
+                const HIDE_OPTIONS: [&str; 6] = [
+                    "verbose",
+                    "verbose_diff",
+                    "file_lines",
+                    "width_heuristics",
+                    "merge_imports",
+                    "fn_args_layout"
+                ];
                 HIDE_OPTIONS.contains(&name)
             }
 
@@ -423,6 +439,18 @@ macro_rules! create_config {
                 }
             }
 
+            fn set_fn_args_layout(&mut self) {
+                if self.was_set().fn_args_layout() {
+                    eprintln!(
+                        "Warning: the `fn_args_layout` option is deprecated. \
+                        Use `fn_params_layout`. instead"
+                    );
+                    if !self.was_set().fn_params_layout() {
+                        self.fn_params_layout.2 = self.fn_args_layout();
+                    }
+                }
+            }
+
             #[allow(unreachable_pub)]
             /// Returns `true` if the config key was explicitly set and is the default value.
             pub fn is_default(&self, key: &str) -> bool {
diff --git a/src/config/macro_names.rs b/src/config/macro_names.rs
new file mode 100644
index 00000000..26ad78d6
--- /dev/null
+++ b/src/config/macro_names.rs
@@ -0,0 +1,118 @@
+//! This module contains types and functions to support formatting specific macros.
+
+use itertools::Itertools;
+use std::{fmt, str};
+
+use serde::{Deserialize, Serialize};
+use serde_json as json;
+use thiserror::Error;
+
+/// Defines the name of a macro.
+#[derive(Clone, Debug, Eq, PartialEq, Hash, Ord, PartialOrd, Deserialize, Serialize)]
+pub struct MacroName(String);
+
+impl MacroName {
+    pub fn new(other: String) -> Self {
+        Self(other)
+    }
+}
+
+impl fmt::Display for MacroName {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        self.0.fmt(f)
+    }
+}
+
+impl From<MacroName> for String {
+    fn from(other: MacroName) -> Self {
+        other.0
+    }
+}
+
+/// Defines a selector to match against a macro.
+#[derive(Clone, Debug, Eq, PartialEq, Hash, Ord, PartialOrd, Deserialize, Serialize)]
+pub enum MacroSelector {
+    Name(MacroName),
+    All,
+}
+
+impl fmt::Display for MacroSelector {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        match self {
+            Self::Name(name) => name.fmt(f),
+            Self::All => write!(f, "*"),
+        }
+    }
+}
+
+impl str::FromStr for MacroSelector {
+    type Err = std::convert::Infallible;
+
+    fn from_str(s: &str) -> Result<Self, Self::Err> {
+        Ok(match s {
+            "*" => MacroSelector::All,
+            name => MacroSelector::Name(MacroName(name.to_owned())),
+        })
+    }
+}
+
+/// A set of macro selectors.
+#[derive(Clone, Debug, Default, PartialEq, Deserialize, Serialize)]
+pub struct MacroSelectors(pub Vec<MacroSelector>);
+
+impl fmt::Display for MacroSelectors {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        write!(f, "{}", self.0.iter().format(", "))
+    }
+}
+
+#[derive(Error, Debug)]
+pub enum MacroSelectorsError {
+    #[error("{0}")]
+    Json(json::Error),
+}
+
+// This impl is needed for `Config::override_value` to work for use in tests.
+impl str::FromStr for MacroSelectors {
+    type Err = MacroSelectorsError;
+
+    fn from_str(s: &str) -> Result<Self, Self::Err> {
+        let raw: Vec<&str> = json::from_str(s).map_err(MacroSelectorsError::Json)?;
+        Ok(Self(
+            raw.into_iter()
+                .map(|raw| {
+                    MacroSelector::from_str(raw).expect("MacroSelector from_str is infallible")
+                })
+                .collect(),
+        ))
+    }
+}
+
+#[cfg(test)]
+mod test {
+    use super::*;
+    use std::str::FromStr;
+
+    #[test]
+    fn macro_names_from_str() {
+        let macro_names = MacroSelectors::from_str(r#"["foo", "*", "bar"]"#).unwrap();
+        assert_eq!(
+            macro_names,
+            MacroSelectors(
+                [
+                    MacroSelector::Name(MacroName("foo".to_owned())),
+                    MacroSelector::All,
+                    MacroSelector::Name(MacroName("bar".to_owned()))
+                ]
+                .into_iter()
+                .collect()
+            )
+        );
+    }
+
+    #[test]
+    fn macro_names_display() {
+        let macro_names = MacroSelectors::from_str(r#"["foo", "*", "bar"]"#).unwrap();
+        assert_eq!(format!("{}", macro_names), "foo, *, bar");
+    }
+}
diff --git a/src/config/mod.rs b/src/config/mod.rs
index eaada8db..5492519f 100644
--- a/src/config/mod.rs
+++ b/src/config/mod.rs
@@ -13,6 +13,8 @@ pub use crate::config::file_lines::{FileLines, FileName, Range};
 #[allow(unreachable_pub)]
 pub use crate::config::lists::*;
 #[allow(unreachable_pub)]
+pub use crate::config::macro_names::{MacroSelector, MacroSelectors};
+#[allow(unreachable_pub)]
 pub use crate::config::options::*;
 
 #[macro_use]
@@ -22,6 +24,7 @@ pub(crate) mod options;
 
 pub(crate) mod file_lines;
 pub(crate) mod lists;
+pub(crate) mod macro_names;
 
 // This macro defines configuration options used in rustfmt. Each option
 // is defined as follows:
@@ -67,6 +70,8 @@ create_config! {
     format_macro_matchers: bool, false, false,
         "Format the metavariable matching patterns in macros";
     format_macro_bodies: bool, true, false, "Format the bodies of macros";
+    skip_macro_invocations: MacroSelectors, MacroSelectors::default(), false,
+        "Skip formatting the bodies of macros invoked with the following names.";
     hex_literal_case: HexLiteralCase, HexLiteralCase::Preserve, false,
         "Format hexadecimal integer literals";
 
@@ -119,7 +124,9 @@ create_config! {
     force_multiline_blocks: bool, false, false,
         "Force multiline closure bodies and match arms to be wrapped in a block";
     fn_args_layout: Density, Density::Tall, true,
-        "Control the layout of arguments in a function";
+        "(deprecated: use fn_params_layout instead)";
+    fn_params_layout: Density, Density::Tall, true,
+        "Control the layout of parameters in function signatures.";
     brace_style: BraceStyle, BraceStyle::SameLineWhere, false, "Brace style for items";
     control_brace_style: ControlBraceStyle, ControlBraceStyle::AlwaysSameLine, false,
         "Brace style for control flow constructs";
@@ -191,6 +198,7 @@ impl PartialConfig {
         cloned.width_heuristics = None;
         cloned.print_misformatted_file_names = None;
         cloned.merge_imports = None;
+        cloned.fn_args_layout = None;
 
         ::toml::to_string(&cloned).map_err(ToTomlError)
     }
@@ -403,6 +411,7 @@ mod test {
     use super::*;
     use std::str;
 
+    use crate::config::macro_names::MacroName;
     use rustfmt_config_proc_macro::{nightly_only_test, stable_only_test};
 
     #[allow(dead_code)]
@@ -436,6 +445,12 @@ mod test {
                 "Merge imports";
             merge_imports: bool, false, false, "(deprecated: use imports_granularity instead)";
 
+            // fn_args_layout renamed to fn_params_layout
+            fn_args_layout: Density, Density::Tall, true,
+                "(deprecated: use fn_params_layout instead)";
+            fn_params_layout: Density, Density::Tall, true,
+                "Control the layout of parameters in a function signatures.";
+
             // Width Heuristics
             use_small_heuristics: Heuristics, Heuristics::Default, true,
                 "Whether to use different formatting for items and \
@@ -611,6 +626,7 @@ normalize_doc_attributes = false
 format_strings = false
 format_macro_matchers = false
 format_macro_bodies = true
+skip_macro_invocations = []
 hex_literal_case = "Preserve"
 empty_item_single_line = true
 struct_lit_single_line = true
@@ -637,7 +653,7 @@ enum_discrim_align_threshold = 0
 match_arm_blocks = true
 match_arm_leading_pipes = "Never"
 force_multiline_blocks = false
-fn_args_layout = "Tall"
+fn_params_layout = "Tall"
 brace_style = "SameLineWhere"
 control_brace_style = "AlwaysSameLine"
 trailing_semicolon = true
@@ -1019,4 +1035,17 @@ make_backup = false
             );
         }
     }
+
+    #[test]
+    fn test_override_skip_macro_invocations() {
+        let mut config = Config::default();
+        config.override_value("skip_macro_invocations", r#"["*", "println"]"#);
+        assert_eq!(
+            config.skip_macro_invocations(),
+            MacroSelectors(vec![
+                MacroSelector::All,
+                MacroSelector::Name(MacroName::new("println".to_owned()))
+            ])
+        );
+    }
 }
diff --git a/src/items.rs b/src/items.rs
index bab881f4..6ab02e7f 100644
--- a/src/items.rs
+++ b/src/items.rs
@@ -2602,7 +2602,7 @@ fn rewrite_params(
         &param_items,
         context
             .config
-            .fn_args_layout()
+            .fn_params_layout()
             .to_list_tactic(param_items.len()),
         Separator::Comma,
         one_line_budget,
diff --git a/src/skip.rs b/src/skip.rs
index 0fdc097e..8b2fd773 100644
--- a/src/skip.rs
+++ b/src/skip.rs
@@ -7,6 +7,7 @@ use rustc_ast_pretty::pprust;
 /// by other context. Query this context to know if you need skip a block.
 #[derive(Default, Clone)]
 pub(crate) struct SkipContext {
+    pub(crate) all_macros: bool,
     macros: Vec<String>,
     attributes: Vec<String>,
 }
@@ -23,8 +24,15 @@ impl SkipContext {
         self.attributes.append(&mut other.attributes);
     }
 
+    pub(crate) fn update_macros<T>(&mut self, other: T)
+    where
+        T: IntoIterator<Item = String>,
+    {
+        self.macros.extend(other.into_iter());
+    }
+
     pub(crate) fn skip_macro(&self, name: &str) -> bool {
-        self.macros.iter().any(|n| n == name)
+        self.all_macros || self.macros.iter().any(|n| n == name)
     }
 
     pub(crate) fn skip_attribute(&self, name: &str) -> bool {
diff --git a/src/visitor.rs b/src/visitor.rs
index 9a0e0752..b93153de 100644
--- a/src/visitor.rs
+++ b/src/visitor.rs
@@ -8,7 +8,7 @@ use rustc_span::{symbol, BytePos, Pos, Span};
 use crate::attr::*;
 use crate::comment::{contains_comment, rewrite_comment, CodeCharKind, CommentCodeSlices};
 use crate::config::Version;
-use crate::config::{BraceStyle, Config};
+use crate::config::{BraceStyle, Config, MacroSelector};
 use crate::coverage::transform_missing_snippet;
 use crate::items::{
     format_impl, format_trait, format_trait_alias, is_mod_decl, is_use_item, rewrite_extern_crate,
@@ -770,6 +770,15 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
         snippet_provider: &'a SnippetProvider,
         report: FormatReport,
     ) -> FmtVisitor<'a> {
+        let mut skip_context = SkipContext::default();
+        let mut macro_names = Vec::new();
+        for macro_selector in config.skip_macro_invocations().0 {
+            match macro_selector {
+                MacroSelector::Name(name) => macro_names.push(name.to_string()),
+                MacroSelector::All => skip_context.all_macros = true,
+            }
+        }
+        skip_context.update_macros(macro_names);
         FmtVisitor {
             parent_context: None,
             parse_sess: parse_session,
@@ -784,7 +793,7 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
             is_macro_def: false,
             macro_rewrite_failure: false,
             report,
-            skip_context: Default::default(),
+            skip_context,
         }
     }
 


Test patch:
diff --git a/src/test/configuration_snippet.rs b/src/test/configuration_snippet.rs
index c8fda7c8..c70b3c5f 100644
--- a/src/test/configuration_snippet.rs
+++ b/src/test/configuration_snippet.rs
@@ -27,8 +27,13 @@ impl ConfigurationSection {
         lazy_static! {
             static ref CONFIG_NAME_REGEX: regex::Regex =
                 regex::Regex::new(r"^## `([^`]+)`").expect("failed creating configuration pattern");
+            // Configuration values, which will be passed to `from_str`:
+            //
+            // - must be prefixed with `####`
+            // - must be wrapped in backticks
+            // - may by wrapped in double quotes (which will be stripped)
             static ref CONFIG_VALUE_REGEX: regex::Regex =
-                regex::Regex::new(r#"^#### `"?([^`"]+)"?`"#)
+                regex::Regex::new(r#"^#### `"?([^`]+?)"?`"#)
                     .expect("failed creating configuration value pattern");
         }
 
diff --git a/tests/config/small_tabs.toml b/tests/config/small_tabs.toml
index c3cfd343..4c371008 100644
--- a/tests/config/small_tabs.toml
+++ b/tests/config/small_tabs.toml
@@ -3,7 +3,7 @@ comment_width = 80
 tab_spaces = 2
 newline_style = "Unix"
 brace_style = "SameLineWhere"
-fn_args_layout = "Tall"
+fn_params_layout = "Tall"
 trailing_comma = "Vertical"
 indent_style = "Block"
 reorder_imports = false
diff --git a/tests/source/configs/fn_args_layout/compressed.rs b/tests/source/configs/fn_params_layout/compressed.rs
similarity index 92%
rename from tests/source/configs/fn_args_layout/compressed.rs
rename to tests/source/configs/fn_params_layout/compressed.rs
index 66a371c2..eb573d31 100644
--- a/tests/source/configs/fn_args_layout/compressed.rs
+++ b/tests/source/configs/fn_params_layout/compressed.rs
@@ -1,4 +1,4 @@
-// rustfmt-fn_args_layout: Compressed
+// rustfmt-fn_params_layout: Compressed
 // Function arguments density
 
 trait Lorem {
diff --git a/tests/source/configs/fn_args_layout/tall.rs b/tests/source/configs/fn_params_layout/tall.rs
similarity index 93%
rename from tests/source/configs/fn_args_layout/tall.rs
rename to tests/source/configs/fn_params_layout/tall.rs
index f11e86fd..4be34f0f 100644
--- a/tests/source/configs/fn_args_layout/tall.rs
+++ b/tests/source/configs/fn_params_layout/tall.rs
@@ -1,4 +1,4 @@
-// rustfmt-fn_args_layout: Tall
+// rustfmt-fn_params_layout: Tall
 // Function arguments density
 
 trait Lorem {
diff --git a/tests/source/configs/fn_args_layout/vertical.rs b/tests/source/configs/fn_params_layout/vertical.rs
similarity index 92%
rename from tests/source/configs/fn_args_layout/vertical.rs
rename to tests/source/configs/fn_params_layout/vertical.rs
index a23cc025..67496802 100644
--- a/tests/source/configs/fn_args_layout/vertical.rs
+++ b/tests/source/configs/fn_params_layout/vertical.rs
@@ -1,4 +1,4 @@
-// rustfmt-fn_args_layout: Vertical
+// rustfmt-fn_params_layout: Vertical
 // Function arguments density
 
 trait Lorem {
diff --git a/tests/source/fn-custom-7.rs b/tests/source/fn-custom-7.rs
index d5330196..3ecd8701 100644
--- a/tests/source/fn-custom-7.rs
+++ b/tests/source/fn-custom-7.rs
@@ -1,5 +1,5 @@
 // rustfmt-normalize_comments: true
-// rustfmt-fn_args_layout: Vertical
+// rustfmt-fn_params_layout: Vertical
 // rustfmt-brace_style: AlwaysNextLine
 
 // Case with only one variable.
diff --git a/tests/source/fn-custom.rs b/tests/source/fn-custom.rs
index 77ced4c5..64ef0ecf 100644
--- a/tests/source/fn-custom.rs
+++ b/tests/source/fn-custom.rs
@@ -1,4 +1,4 @@
-// rustfmt-fn_args_layout: Compressed
+// rustfmt-fn_params_layout: Compressed
 // Test some of the ways function signatures can be customised.
 
 // Test compressed layout of args.
diff --git a/tests/source/fn_args_layout-vertical.rs b/tests/source/fn_args_layout-vertical.rs
index 759bc83d..fd6e3f04 100644
--- a/tests/source/fn_args_layout-vertical.rs
+++ b/tests/source/fn_args_layout-vertical.rs
@@ -1,4 +1,4 @@
-// rustfmt-fn_args_layout: Vertical
+// rustfmt-fn_params_layout: Vertical
 
 // Empty list should stay on one line.
 fn do_bar(
diff --git a/tests/source/skip_macro_invocations/all.rs b/tests/source/skip_macro_invocations/all.rs
new file mode 100644
index 00000000..d0437ee1
--- /dev/null
+++ b/tests/source/skip_macro_invocations/all.rs
@@ -0,0 +1,11 @@
+// rustfmt-skip_macro_invocations: ["*"]
+
+// Should skip this invocation
+items!(
+        const _: u8 = 0;
+);
+
+// Should skip this invocation
+renamed_items!(
+        const _: u8 = 0;
+);
diff --git a/tests/source/skip_macro_invocations/all_and_name.rs b/tests/source/skip_macro_invocations/all_and_name.rs
new file mode 100644
index 00000000..1f672234
--- /dev/null
+++ b/tests/source/skip_macro_invocations/all_and_name.rs
@@ -0,0 +1,11 @@
+// rustfmt-skip_macro_invocations: ["*","items"]
+
+// Should skip this invocation
+items!(
+        const _: u8 = 0;
+);
+
+// Should also skip this invocation, as the wildcard covers it
+renamed_items!(
+        const _: u8 = 0;
+);
diff --git a/tests/source/skip_macro_invocations/empty.rs b/tests/source/skip_macro_invocations/empty.rs
new file mode 100644
index 00000000..f3dd89dc
--- /dev/null
+++ b/tests/source/skip_macro_invocations/empty.rs
@@ -0,0 +1,11 @@
+// rustfmt-skip_macro_invocations: []
+
+// Should not skip this invocation
+items!(
+        const _: u8 = 0;
+);
+
+// Should not skip this invocation
+renamed_items!(
+        const _: u8 = 0;
+);
diff --git a/tests/source/skip_macro_invocations/name.rs b/tests/source/skip_macro_invocations/name.rs
new file mode 100644
index 00000000..7fa5d3a6
--- /dev/null
+++ b/tests/source/skip_macro_invocations/name.rs
@@ -0,0 +1,11 @@
+// rustfmt-skip_macro_invocations: ["items"]
+
+// Should skip this invocation
+items!(
+        const _: u8 = 0;
+);
+
+// Should not skip this invocation
+renamed_items!(
+        const _: u8 = 0;
+);
diff --git a/tests/source/skip_macro_invocations/name_unknown.rs b/tests/source/skip_macro_invocations/name_unknown.rs
new file mode 100644
index 00000000..d5669532
--- /dev/null
+++ b/tests/source/skip_macro_invocations/name_unknown.rs
@@ -0,0 +1,6 @@
+// rustfmt-skip_macro_invocations: ["unknown"]
+
+// Should not skip this invocation
+items!(
+        const _: u8 = 0;
+);
diff --git a/tests/source/skip_macro_invocations/names.rs b/tests/source/skip_macro_invocations/names.rs
new file mode 100644
index 00000000..a920381a
--- /dev/null
+++ b/tests/source/skip_macro_invocations/names.rs
@@ -0,0 +1,16 @@
+// rustfmt-skip_macro_invocations: ["foo","bar"]
+
+// Should skip this invocation
+foo!(
+        const _: u8 = 0;
+);
+
+// Should skip this invocation
+bar!(
+        const _: u8 = 0;
+);
+
+// Should not skip this invocation
+baz!(
+        const _: u8 = 0;
+);
diff --git a/tests/source/skip_macro_invocations/path_qualified_invocation_mismatch.rs b/tests/source/skip_macro_invocations/path_qualified_invocation_mismatch.rs
new file mode 100644
index 00000000..61296869
--- /dev/null
+++ b/tests/source/skip_macro_invocations/path_qualified_invocation_mismatch.rs
@@ -0,0 +1,6 @@
+// rustfmt-skip_macro_invocations: ["items"]
+
+// Should not skip this invocation
+self::items!(
+        const _: u8 = 0;
+);
diff --git a/tests/source/skip_macro_invocations/path_qualified_match.rs b/tests/source/skip_macro_invocations/path_qualified_match.rs
new file mode 100644
index 00000000..9398918a
--- /dev/null
+++ b/tests/source/skip_macro_invocations/path_qualified_match.rs
@@ -0,0 +1,6 @@
+// rustfmt-skip_macro_invocations: ["self::items"]
+
+// Should skip this invocation
+self::items!(
+        const _: u8 = 0;
+);
diff --git a/tests/source/skip_macro_invocations/path_qualified_name_mismatch.rs b/tests/source/skip_macro_invocations/path_qualified_name_mismatch.rs
new file mode 100644
index 00000000..4e3eb542
--- /dev/null
+++ b/tests/source/skip_macro_invocations/path_qualified_name_mismatch.rs
@@ -0,0 +1,6 @@
+// rustfmt-skip_macro_invocations: ["self::items"]
+
+// Should not skip this invocation
+items!(
+        const _: u8 = 0;
+);
diff --git a/tests/source/skip_macro_invocations/use_alias_examples.rs b/tests/source/skip_macro_invocations/use_alias_examples.rs
new file mode 100644
index 00000000..43cb8015
--- /dev/null
+++ b/tests/source/skip_macro_invocations/use_alias_examples.rs
@@ -0,0 +1,32 @@
+// rustfmt-skip_macro_invocations: ["aaa","ccc"]
+
+// These tests demonstrate a realistic use case with use aliases.
+// The use statements should not impact functionality in any way.
+
+use crate::{aaa, bbb, ddd};
+
+// No use alias, invocation in list
+// Should skip this invocation
+aaa!(
+        const _: u8 = 0;
+);
+
+// Use alias, invocation in list
+// Should skip this invocation
+use crate::bbb as ccc;
+ccc!(
+        const _: u8 = 0;
+);
+
+// Use alias, invocation not in list
+// Should not skip this invocation
+use crate::ddd as eee;
+eee!(
+        const _: u8 = 0;
+);
+
+// No use alias, invocation not in list
+// Should not skip this invocation
+fff!(
+        const _: u8 = 0;
+);
diff --git a/tests/target/configs/fn_args_layout/compressed.rs b/tests/target/configs/fn_params_layout/compressed.rs
similarity index 92%
rename from tests/target/configs/fn_args_layout/compressed.rs
rename to tests/target/configs/fn_params_layout/compressed.rs
index f189446e..ff32f0f1 100644
--- a/tests/target/configs/fn_args_layout/compressed.rs
+++ b/tests/target/configs/fn_params_layout/compressed.rs
@@ -1,4 +1,4 @@
-// rustfmt-fn_args_layout: Compressed
+// rustfmt-fn_params_layout: Compressed
 // Function arguments density
 
 trait Lorem {
diff --git a/tests/target/configs/fn_args_layout/tall.rs b/tests/target/configs/fn_params_layout/tall.rs
similarity index 94%
rename from tests/target/configs/fn_args_layout/tall.rs
rename to tests/target/configs/fn_params_layout/tall.rs
index 20f30897..25a86799 100644
--- a/tests/target/configs/fn_args_layout/tall.rs
+++ b/tests/target/configs/fn_params_layout/tall.rs
@@ -1,4 +1,4 @@
-// rustfmt-fn_args_layout: Tall
+// rustfmt-fn_params_layout: Tall
 // Function arguments density
 
 trait Lorem {
diff --git a/tests/target/configs/fn_args_layout/vertical.rs b/tests/target/configs/fn_params_layout/vertical.rs
similarity index 94%
rename from tests/target/configs/fn_args_layout/vertical.rs
rename to tests/target/configs/fn_params_layout/vertical.rs
index 6c695a75..7a0e4241 100644
--- a/tests/target/configs/fn_args_layout/vertical.rs
+++ b/tests/target/configs/fn_params_layout/vertical.rs
@@ -1,4 +1,4 @@
-// rustfmt-fn_args_layout: Vertical
+// rustfmt-fn_params_layout: Vertical
 // Function arguments density
 
 trait Lorem {
diff --git a/tests/target/fn-custom-7.rs b/tests/target/fn-custom-7.rs
index 2c20ac5a..f6a1a90c 100644
--- a/tests/target/fn-custom-7.rs
+++ b/tests/target/fn-custom-7.rs
@@ -1,5 +1,5 @@
 // rustfmt-normalize_comments: true
-// rustfmt-fn_args_layout: Vertical
+// rustfmt-fn_params_layout: Vertical
 // rustfmt-brace_style: AlwaysNextLine
 
 // Case with only one variable.
diff --git a/tests/target/fn-custom.rs b/tests/target/fn-custom.rs
index 2eb2a973..506d9de3 100644
--- a/tests/target/fn-custom.rs
+++ b/tests/target/fn-custom.rs
@@ -1,4 +1,4 @@
-// rustfmt-fn_args_layout: Compressed
+// rustfmt-fn_params_layout: Compressed
 // Test some of the ways function signatures can be customised.
 
 // Test compressed layout of args.
diff --git a/tests/target/fn_args_layout-vertical.rs b/tests/target/fn_args_layout-vertical.rs
index da0ac981..bfeca15c 100644
--- a/tests/target/fn_args_layout-vertical.rs
+++ b/tests/target/fn_args_layout-vertical.rs
@@ -1,4 +1,4 @@
-// rustfmt-fn_args_layout: Vertical
+// rustfmt-fn_params_layout: Vertical
 
 // Empty list should stay on one line.
 fn do_bar() -> u8 {
diff --git a/tests/target/issue-4791/issue_4928.rs b/tests/target/issue-4791/issue_4928.rs
index 588656b5..29f6bda9 100644
--- a/tests/target/issue-4791/issue_4928.rs
+++ b/tests/target/issue-4791/issue_4928.rs
@@ -1,7 +1,7 @@
 // rustfmt-brace_style: SameLineWhere
 // rustfmt-comment_width: 100
 // rustfmt-edition: 2018
-// rustfmt-fn_args_layout: Compressed
+// rustfmt-fn_params_layout: Compressed
 // rustfmt-hard_tabs: false
 // rustfmt-match_block_trailing_comma: true
 // rustfmt-max_width: 100
diff --git a/tests/target/skip_macro_invocations/all.rs b/tests/target/skip_macro_invocations/all.rs
new file mode 100644
index 00000000..d0437ee1
--- /dev/null
+++ b/tests/target/skip_macro_invocations/all.rs
@@ -0,0 +1,11 @@
+// rustfmt-skip_macro_invocations: ["*"]
+
+// Should skip this invocation
+items!(
+        const _: u8 = 0;
+);
+
+// Should skip this invocation
+renamed_items!(
+        const _: u8 = 0;
+);
diff --git a/tests/target/skip_macro_invocations/all_and_name.rs b/tests/target/skip_macro_invocations/all_and_name.rs
new file mode 100644
index 00000000..1f672234
--- /dev/null
+++ b/tests/target/skip_macro_invocations/all_and_name.rs
@@ -0,0 +1,11 @@
+// rustfmt-skip_macro_invocations: ["*","items"]
+
+// Should skip this invocation
+items!(
+        const _: u8 = 0;
+);
+
+// Should also skip this invocation, as the wildcard covers it
+renamed_items!(
+        const _: u8 = 0;
+);
diff --git a/tests/target/skip_macro_invocations/empty.rs b/tests/target/skip_macro_invocations/empty.rs
new file mode 100644
index 00000000..4a398cc5
--- /dev/null
+++ b/tests/target/skip_macro_invocations/empty.rs
@@ -0,0 +1,11 @@
+// rustfmt-skip_macro_invocations: []
+
+// Should not skip this invocation
+items!(
+    const _: u8 = 0;
+);
+
+// Should not skip this invocation
+renamed_items!(
+    const _: u8 = 0;
+);
diff --git a/tests/target/skip_macro_invocations/name.rs b/tests/target/skip_macro_invocations/name.rs
new file mode 100644
index 00000000..c4d57726
--- /dev/null
+++ b/tests/target/skip_macro_invocations/name.rs
@@ -0,0 +1,11 @@
+// rustfmt-skip_macro_invocations: ["items"]
+
+// Should skip this invocation
+items!(
+        const _: u8 = 0;
+);
+
+// Should not skip this invocation
+renamed_items!(
+    const _: u8 = 0;
+);
diff --git a/tests/target/skip_macro_invocations/name_unknown.rs b/tests/target/skip_macro_invocations/name_unknown.rs
new file mode 100644
index 00000000..7ab14403
--- /dev/null
+++ b/tests/target/skip_macro_invocations/name_unknown.rs
@@ -0,0 +1,6 @@
+// rustfmt-skip_macro_invocations: ["unknown"]
+
+// Should not skip this invocation
+items!(
+    const _: u8 = 0;
+);
diff --git a/tests/target/skip_macro_invocations/names.rs b/tests/target/skip_macro_invocations/names.rs
new file mode 100644
index 00000000..c6b41ff9
--- /dev/null
+++ b/tests/target/skip_macro_invocations/names.rs
@@ -0,0 +1,16 @@
+// rustfmt-skip_macro_invocations: ["foo","bar"]
+
+// Should skip this invocation
+foo!(
+        const _: u8 = 0;
+);
+
+// Should skip this invocation
+bar!(
+        const _: u8 = 0;
+);
+
+// Should not skip this invocation
+baz!(
+    const _: u8 = 0;
+);
diff --git a/tests/target/skip_macro_invocations/path_qualified_invocation_mismatch.rs b/tests/target/skip_macro_invocations/path_qualified_invocation_mismatch.rs
new file mode 100644
index 00000000..6e372c72
--- /dev/null
+++ b/tests/target/skip_macro_invocations/path_qualified_invocation_mismatch.rs
@@ -0,0 +1,6 @@
+// rustfmt-skip_macro_invocations: ["items"]
+
+// Should not skip this invocation
+self::items!(
+    const _: u8 = 0;
+);
diff --git a/tests/target/skip_macro_invocations/path_qualified_match.rs b/tests/target/skip_macro_invocations/path_qualified_match.rs
new file mode 100644
index 00000000..9398918a
--- /dev/null
+++ b/tests/target/skip_macro_invocations/path_qualified_match.rs
@@ -0,0 +1,6 @@
+// rustfmt-skip_macro_invocations: ["self::items"]
+
+// Should skip this invocation
+self::items!(
+        const _: u8 = 0;
+);
diff --git a/tests/target/skip_macro_invocations/path_qualified_name_mismatch.rs b/tests/target/skip_macro_invocations/path_qualified_name_mismatch.rs
new file mode 100644
index 00000000..aa57a2a6
--- /dev/null
+++ b/tests/target/skip_macro_invocations/path_qualified_name_mismatch.rs
@@ -0,0 +1,6 @@
+// rustfmt-skip_macro_invocations: ["self::items"]
+
+// Should not skip this invocation
+items!(
+    const _: u8 = 0;
+);
diff --git a/tests/target/skip_macro_invocations/use_alias_examples.rs b/tests/target/skip_macro_invocations/use_alias_examples.rs
new file mode 100644
index 00000000..799dd8c0
--- /dev/null
+++ b/tests/target/skip_macro_invocations/use_alias_examples.rs
@@ -0,0 +1,32 @@
+// rustfmt-skip_macro_invocations: ["aaa","ccc"]
+
+// These tests demonstrate a realistic use case with use aliases.
+// The use statements should not impact functionality in any way.
+
+use crate::{aaa, bbb, ddd};
+
+// No use alias, invocation in list
+// Should skip this invocation
+aaa!(
+        const _: u8 = 0;
+);
+
+// Use alias, invocation in list
+// Should skip this invocation
+use crate::bbb as ccc;
+ccc!(
+        const _: u8 = 0;
+);
+
+// Use alias, invocation not in list
+// Should not skip this invocation
+use crate::ddd as eee;
+eee!(
+    const _: u8 = 0;
+);
+
+// No use alias, invocation not in list
+// Should not skip this invocation
+fff!(
+    const _: u8 = 0;
+);