Upgrade clap to 4.1.8 am: f0f5837f59 am: be31cd74d2

Original change: https://android-review.googlesource.com/c/platform/external/rust/crates/clap/+/2465998

Change-Id: I06ff39c77527d5063eb0d0fbeb843083987a2e07
Signed-off-by: Automerger Merge Worker <[email protected]>
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json
index 3582b8c..382d047 100644
--- a/.cargo_vcs_info.json
+++ b/.cargo_vcs_info.json
@@ -1,6 +1,6 @@
 {
   "git": {
-    "sha1": "ad4726378b2ee0320bbab5569acd8869a402e9fd"
+    "sha1": "f931de694a5478d7e4bd424613e6699f7d4f4e9f"
   },
   "path_in_vcs": ""
 }
\ No newline at end of file
diff --git a/Android.bp b/Android.bp
index b925e74..1ef7b16 100644
--- a/Android.bp
+++ b/Android.bp
@@ -42,7 +42,7 @@
     host_supported: true,
     crate_name: "clap",
     cargo_env_compat: true,
-    cargo_pkg_version: "4.0.29",
+    cargo_pkg_version: "4.1.8",
     srcs: ["src/lib.rs"],
     edition: "2021",
     features: [
@@ -67,7 +67,7 @@
     host_supported: true,
     crate_name: "stdio_fixture",
     cargo_env_compat: true,
-    cargo_pkg_version: "4.0.29",
+    cargo_pkg_version: "4.1.8",
     srcs: ["src/bin/stdio-fixture.rs"],
     edition: "2021",
     features: [
diff --git a/Cargo.toml b/Cargo.toml
index a40a3e2..fc59af3 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -11,9 +11,9 @@
 
 [package]
 edition = "2021"
-rust-version = "1.60.0"
+rust-version = "1.64.0"
 name = "clap"
-version = "4.0.29"
+version = "4.1.8"
 include = [
     "build.rs",
     "src/**/*",
@@ -363,7 +363,7 @@
 version = "1.2"
 
 [dependencies.clap_derive]
-version = "=4.0.21"
+version = "=4.1.8"
 optional = true
 
 [dependencies.clap_lex]
@@ -413,10 +413,10 @@
 version = "1.1.0"
 
 [dev-dependencies.trybuild]
-version = "1.0.71"
+version = "1.0.73"
 
 [dev-dependencies.trycmd]
-version = "0.14.3"
+version = "0.14.9"
 features = [
     "color-auto",
     "diff",
@@ -471,7 +471,6 @@
     "unicode",
     "string",
     "unstable-replace",
-    "unstable-grouped",
 ]
 unstable-grouped = []
 unstable-replace = []
diff --git a/Cargo.toml.orig b/Cargo.toml.orig
index 7660ea5..fac36f6 100644
--- a/Cargo.toml.orig
+++ b/Cargo.toml.orig
@@ -8,9 +8,23 @@
   "clap_mangen",
 ]
 
+[workspace.package]
+license = "MIT OR Apache-2.0"
+edition = "2021"
+rust-version = "1.64.0"  # MSRV
+include = [
+  "build.rs",
+  "src/**/*",
+  "Cargo.toml",
+  "LICENSE*",
+  "README.md",
+  "benches/**/*",
+  "examples/**/*"
+]
+
 [package]
 name = "clap"
-version = "4.0.29"
+version = "4.1.8"
 description = "A simple to use, efficient, and full-featured Command Line Argument Parser"
 repository = "https://github.com/clap-rs/clap"
 categories = ["command-line-interface"]
@@ -21,18 +35,10 @@
   "parser",
   "parse"
 ]
-license = "MIT OR Apache-2.0"
-edition = "2021"
-rust-version = "1.60.0"  # MSRV
-include = [
-  "build.rs",
-  "src/**/*",
-  "Cargo.toml",
-  "LICENSE*",
-  "README.md",
-  "benches/**/*",
-  "examples/**/*"
-]
+license.workspace = true
+edition.workspace = true
+rust-version.workspace = true
+include.workspace = true
 
 [package.metadata.docs.rs]
 features = ["unstable-doc"]
@@ -63,7 +69,7 @@
   "suggestions",
 ]
 debug = ["clap_derive?/debug", "dep:backtrace"] # Enables debug messages
-unstable-doc = ["derive", "cargo", "wrap_help", "env", "unicode", "string", "unstable-replace", "unstable-grouped"] # for docs.rs
+unstable-doc = ["derive", "cargo", "wrap_help", "env", "unicode", "string", "unstable-replace"] # for docs.rs
 
 # Used in default
 std = [] # support for no_std in a backwards-compatible way
@@ -91,7 +97,7 @@
 bench = false
 
 [dependencies]
-clap_derive = { path = "./clap_derive", version = "=4.0.21", optional = true }
+clap_derive = { path = "./clap_derive", version = "=4.1.8", optional = true }
 clap_lex = { path = "./clap_lex", version = "0.3.0" }
 bitflags = "1.2"
 unicase = { version = "2.6", optional = true }
@@ -104,10 +110,10 @@
 once_cell = { version = "1.12.0", optional = true }
 
 [dev-dependencies]
-trybuild = "1.0.71"
+trybuild = "1.0.73"
 rustversion = "1"
 # Cutting out `filesystem` feature
-trycmd = { version = "0.14.3", default-features = false, features = ["color-auto", "diff", "examples"] }
+trycmd = { version = "0.14.9", default-features = false, features = ["color-auto", "diff", "examples"] }
 humantime = "2"
 snapbox = "0.4"
 shlex = "1.1.0"
diff --git a/METADATA b/METADATA
index fc7fe6c..ac42e03 100644
--- a/METADATA
+++ b/METADATA
@@ -11,13 +11,13 @@
   }
   url {
     type: ARCHIVE
-    value: "https://static.crates.io/crates/clap/clap-4.0.29.crate"
+    value: "https://static.crates.io/crates/clap/clap-4.1.8.crate"
   }
-  version: "4.0.29"
+  version: "4.1.8"
   license_type: NOTICE
   last_upgrade_date {
-    year: 2022
-    month: 11
-    day: 30
+    year: 2023
+    month: 3
+    day: 2
   }
 }
diff --git a/README.md b/README.md
index eea6ba6..b1298f8 100644
--- a/README.md
+++ b/README.md
@@ -6,7 +6,7 @@
 [![Crates.io](https://img.shields.io/crates/d/clap?style=flat-square)](https://crates.io/crates/clap)
 [![License](https://img.shields.io/badge/license-Apache%202.0-blue?style=flat-square)](LICENSE-APACHE)
 [![License](https://img.shields.io/badge/license-MIT-blue?style=flat-square)](LICENSE-MIT)
-[![Build Status](https://img.shields.io/github/workflow/status/clap-rs/clap/CI/staging?style=flat-square)](https://github.com/clap-rs/clap/actions/workflows/ci.yml?query=branch%3Astaging)
+[![Build Status](https://img.shields.io/github/actions/workflow/status/clap-rs/clap/ci.yml?branch=master&style=flat-square)](https://github.com/clap-rs/clap/actions/workflows/ci.yml?query=branch%3Amaster)
 [![Coverage Status](https://img.shields.io/coveralls/github/clap-rs/clap/master?style=flat-square)](https://coveralls.io/github/clap-rs/clap?branch=master)
 [![Contributors](https://img.shields.io/github/contributors/clap-rs/clap?style=flat-square)](https://github.com/clap-rs/clap/graphs/contributors)
 
diff --git a/examples/cargo-example-derive.md b/examples/cargo-example-derive.md
index 99cbb2f..a3dcef3 100644
--- a/examples/cargo-example-derive.md
+++ b/examples/cargo-example-derive.md
@@ -13,7 +13,7 @@
   help            Print this message or the help of the given subcommand(s)
 
 Options:
-  -h, --help  Print help information
+  -h, --help  Print help
 
 $ cargo-example-derive example-derive --help
 A simple to use, efficient, and full-featured Command Line Argument Parser
@@ -22,8 +22,8 @@
 
 Options:
       --manifest-path <MANIFEST_PATH>  
-  -h, --help                           Print help information
-  -V, --version                        Print version information
+  -h, --help                           Print help
+  -V, --version                        Print version
 
 ```
 
diff --git a/examples/cargo-example-derive.rs b/examples/cargo-example-derive.rs
index d9603db..dfdd799 100644
--- a/examples/cargo-example-derive.rs
+++ b/examples/cargo-example-derive.rs
@@ -3,18 +3,18 @@
 #[derive(Parser)] // requires `derive` feature
 #[command(name = "cargo")]
 #[command(bin_name = "cargo")]
-enum Cargo {
-    ExampleDerive(ExampleDerive),
+enum CargoCli {
+    ExampleDerive(ExampleDeriveArgs),
 }
 
 #[derive(clap::Args)]
 #[command(author, version, about, long_about = None)]
-struct ExampleDerive {
+struct ExampleDeriveArgs {
     #[arg(long)]
     manifest_path: Option<std::path::PathBuf>,
 }
 
 fn main() {
-    let Cargo::ExampleDerive(args) = Cargo::parse();
+    let CargoCli::ExampleDerive(args) = CargoCli::parse();
     println!("{:?}", args.manifest_path);
 }
diff --git a/examples/cargo-example.md b/examples/cargo-example.md
index caafbad..edf8ee1 100644
--- a/examples/cargo-example.md
+++ b/examples/cargo-example.md
@@ -13,7 +13,7 @@
   help     Print this message or the help of the given subcommand(s)
 
 Options:
-  -h, --help  Print help information
+  -h, --help  Print help
 
 $ cargo-example example --help
 A simple to use, efficient, and full-featured Command Line Argument Parser
@@ -22,8 +22,8 @@
 
 Options:
       --manifest-path <PATH>  
-  -h, --help                  Print help information
-  -V, --version               Print version information
+  -h, --help                  Print help
+  -V, --version               Print version
 
 ```
 
diff --git a/examples/demo.md b/examples/demo.md
index 2a9ed94..772d98d 100644
--- a/examples/demo.md
+++ b/examples/demo.md
@@ -7,8 +7,8 @@
 Options:
   -n, --name <NAME>    Name of the person to greet
   -c, --count <COUNT>  Number of times to greet [default: 1]
-  -h, --help           Print help information
-  -V, --version        Print version information
+  -h, --help           Print help
+  -V, --version        Print version
 
 $ demo --name Me
 Hello Me!
diff --git a/examples/derive_ref/augment_args.rs b/examples/derive_ref/augment_args.rs
index 458beb4..39d837c 100644
--- a/examples/derive_ref/augment_args.rs
+++ b/examples/derive_ref/augment_args.rs
@@ -23,5 +23,5 @@
     let derived_matches = DerivedArgs::from_arg_matches(&matches)
         .map_err(|err| err.exit())
         .unwrap();
-    println!("Value of derived: {:#?}", derived_matches);
+    println!("Value of derived: {derived_matches:#?}");
 }
diff --git a/examples/derive_ref/augment_subcommands.rs b/examples/derive_ref/augment_subcommands.rs
index 5775275..51cbe75 100644
--- a/examples/derive_ref/augment_subcommands.rs
+++ b/examples/derive_ref/augment_subcommands.rs
@@ -17,5 +17,5 @@
     let derived_subcommands = Subcommands::from_arg_matches(&matches)
         .map_err(|err| err.exit())
         .unwrap();
-    println!("Derived subcommands: {:#?}", derived_subcommands);
+    println!("Derived subcommands: {derived_subcommands:#?}");
 }
diff --git a/examples/derive_ref/flatten_hand_args.rs b/examples/derive_ref/flatten_hand_args.rs
index 2ceeb7c..36aac09 100644
--- a/examples/derive_ref/flatten_hand_args.rs
+++ b/examples/derive_ref/flatten_hand_args.rs
@@ -87,5 +87,5 @@
 
 fn main() {
     let args = Cli::parse();
-    println!("{:#?}", args);
+    println!("{args:#?}");
 }
diff --git a/examples/derive_ref/hand_subcommand.rs b/examples/derive_ref/hand_subcommand.rs
index 5ea169c..ebaa60d 100644
--- a/examples/derive_ref/hand_subcommand.rs
+++ b/examples/derive_ref/hand_subcommand.rs
@@ -69,11 +69,11 @@
 struct Cli {
     #[arg(short, long)]
     top_level: bool,
-    #[clap(subcommand)]
+    #[command(subcommand)]
     subcommand: CliSub,
 }
 
 fn main() {
     let args = Cli::parse();
-    println!("{:#?}", args);
+    println!("{args:#?}");
 }
diff --git a/examples/derive_ref/interop_tests.md b/examples/derive_ref/interop_tests.md
index b013b0c..a7bcc7e 100644
--- a/examples/derive_ref/interop_tests.md
+++ b/examples/derive_ref/interop_tests.md
@@ -35,11 +35,11 @@
 ```console
 $ interop_augment_args --unknown
 ? failed
-error: Found argument '--unknown' which wasn't expected, or isn't valid in this context
+error: unexpected argument '--unknown' found
 
 Usage: interop_augment_args[EXE] [OPTIONS]
 
-For more information try '--help'
+For more information, try '--help'.
 
 ```
 
@@ -70,22 +70,22 @@
 ```console
 $ interop_augment_subcommands derived --unknown
 ? failed
-error: Found argument '--unknown' which wasn't expected, or isn't valid in this context
+error: unexpected argument '--unknown' found
 
 Usage: interop_augment_subcommands[EXE] derived [OPTIONS]
 
-For more information try '--help'
+For more information, try '--help'.
 
 ```
 
 ```console
 $ interop_augment_subcommands unknown
 ? failed
-error: The subcommand 'unknown' wasn't recognized
+error: unrecognized subcommand 'unknown'
 
 Usage: interop_augment_subcommands[EXE] [COMMAND]
 
-For more information try '--help'
+For more information, try '--help'.
 
 ```
 
@@ -103,7 +103,7 @@
 
 Options:
   -t, --top-level  
-  -h, --help       Print help information
+  -h, --help       Print help
 
 ```
 
@@ -140,13 +140,13 @@
 ```console
 $ interop_hand_subcommand add --unknown
 ? failed
-error: Found argument '--unknown' which wasn't expected, or isn't valid in this context
+error: unexpected argument '--unknown' found
 
-  If you tried to supply '--unknown' as a value rather than a flag, use '-- --unknown'
+  note: to pass '--unknown' as a value, use '-- --unknown'
 
 Usage: interop_hand_subcommand[EXE] add [NAME]...
 
-For more information try '--help'
+For more information, try '--help'.
 
 ```
 
@@ -185,11 +185,11 @@
 ```console
 $ interop_hand_subcommand unknown
 ? failed
-error: The subcommand 'unknown' wasn't recognized
+error: unrecognized subcommand 'unknown'
 
 Usage: interop_hand_subcommand[EXE] [OPTIONS] <COMMAND>
 
-For more information try '--help'
+For more information, try '--help'.
 
 ```
 
@@ -239,10 +239,10 @@
 ```console
 $ interop_flatten_hand_args --unknown
 ? failed
-error: Found argument '--unknown' which wasn't expected, or isn't valid in this context
+error: unexpected argument '--unknown' found
 
 Usage: interop_flatten_hand_args[EXE] [OPTIONS]
 
-For more information try '--help'
+For more information, try '--help'.
 
 ```
diff --git a/examples/escaped-positional-derive.md b/examples/escaped-positional-derive.md
index cd52add..82990b5 100644
--- a/examples/escaped-positional-derive.md
+++ b/examples/escaped-positional-derive.md
@@ -15,8 +15,8 @@
 Options:
   -f             
   -p <PEAR>      
-  -h, --help     Print help information
-  -V, --version  Print version information
+  -h, --help     Print help
+  -V, --version  Print version
 
 ```
 
@@ -33,11 +33,11 @@
 ```console
 $ escaped-positional-derive foo bar
 ? failed
-error: Found argument 'foo' which wasn't expected, or isn't valid in this context
+error: unexpected argument 'foo' found
 
 Usage: escaped-positional-derive[EXE] [OPTIONS] [-- <SLOP>...]
 
-For more information try '--help'
+For more information, try '--help'.
 
 ```
 
diff --git a/examples/escaped-positional.md b/examples/escaped-positional.md
index 6015cc3..d94e399 100644
--- a/examples/escaped-positional.md
+++ b/examples/escaped-positional.md
@@ -15,8 +15,8 @@
 Options:
   -f             
   -p <PEAR>      
-  -h, --help     Print help information
-  -V, --version  Print version information
+  -h, --help     Print help
+  -V, --version  Print version
 
 ```
 
@@ -33,11 +33,11 @@
 ```console
 $ escaped-positional foo bar
 ? failed
-error: Found argument 'foo' which wasn't expected, or isn't valid in this context
+error: unexpected argument 'foo' found
 
 Usage: escaped-positional[EXE] [OPTIONS] [-- <SLOP>...]
 
-For more information try '--help'
+For more information, try '--help'.
 
 ```
 
diff --git a/examples/find.md b/examples/find.md
index 6388d47..e9b1a86 100644
--- a/examples/find.md
+++ b/examples/find.md
@@ -7,8 +7,8 @@
 Usage: find[EXE] [OPTIONS]
 
 Options:
-  -h, --help     Print help information
-  -V, --version  Print version information
+  -h, --help     Print help
+  -V, --version  Print version
 
 TESTS:
       --empty        File is empty and is either a regular file or a directory
diff --git a/examples/git-derive.md b/examples/git-derive.md
index a4769de..57edb61 100644
--- a/examples/git-derive.md
+++ b/examples/git-derive.md
@@ -19,7 +19,7 @@
   help   Print this message or the help of the given subcommand(s)
 
 Options:
-  -h, --help  Print help information
+  -h, --help  Print help
 
 $ git-derive help
 A fictional versioning CLI
@@ -35,7 +35,7 @@
   help   Print this message or the help of the given subcommand(s)
 
 Options:
-  -h, --help  Print help information
+  -h, --help  Print help
 
 $ git-derive help add
 adds things
@@ -46,7 +46,7 @@
   <PATH>...  Stuff to add
 
 Options:
-  -h, --help  Print help information
+  -h, --help  Print help
 
 ```
 
@@ -62,7 +62,7 @@
   <PATH>...  Stuff to add
 
 Options:
-  -h, --help  Print help information
+  -h, --help  Print help
 
 $ git-derive add Cargo.toml Cargo.lock
 Adding ["Cargo.toml", "Cargo.lock"]
@@ -83,14 +83,14 @@
 
 Options:
   -m, --message <MESSAGE>  
-  -h, --help               Print help information
+  -h, --help               Print help
 
 $ git-derive stash push -h
 Usage: git-derive[EXE] stash push [OPTIONS]
 
 Options:
   -m, --message <MESSAGE>  
-  -h, --help               Print help information
+  -h, --help               Print help
 
 $ git-derive stash pop -h
 Usage: git-derive[EXE] stash pop [STASH]
@@ -99,16 +99,16 @@
   [STASH]  
 
 Options:
-  -h, --help  Print help information
+  -h, --help  Print help
 
 $ git-derive stash -m "Prototype"
-Pushing StashPush { message: Some("Prototype") }
+Pushing StashPushArgs { message: Some("Prototype") }
 
 $ git-derive stash pop
 Popping None
 
 $ git-derive stash push -m "Prototype"
-Pushing StashPush { message: Some("Prototype") }
+Pushing StashPushArgs { message: Some("Prototype") }
 
 $ git-derive stash pop
 Popping None
@@ -136,7 +136,7 @@
 
 Options:
       --color[=<WHEN>]  [default: auto] [possible values: always, auto, never]
-  -h, --help            Print help information
+  -h, --help            Print help
 
 $ git-derive diff
 Diffing stage..worktree  (color=auto)
diff --git a/examples/git-derive.rs b/examples/git-derive.rs
index 519982d..ad82e0c 100644
--- a/examples/git-derive.rs
+++ b/examples/git-derive.rs
@@ -53,7 +53,7 @@
         #[arg(required = true)]
         path: Vec<PathBuf>,
     },
-    Stash(Stash),
+    Stash(StashArgs),
     #[command(external_subcommand)]
     External(Vec<OsString>),
 }
@@ -76,23 +76,23 @@
 
 #[derive(Debug, Args)]
 #[command(args_conflicts_with_subcommands = true)]
-struct Stash {
+struct StashArgs {
     #[command(subcommand)]
     command: Option<StashCommands>,
 
     #[command(flatten)]
-    push: StashPush,
+    push: StashPushArgs,
 }
 
 #[derive(Debug, Subcommand)]
 enum StashCommands {
-    Push(StashPush),
+    Push(StashPushArgs),
     Pop { stash: Option<String> },
     Apply { stash: Option<String> },
 }
 
 #[derive(Debug, Args)]
-struct StashPush {
+struct StashPushArgs {
     #[arg(short, long)]
     message: Option<String>,
 }
@@ -102,7 +102,7 @@
 
     match args.command {
         Commands::Clone { remote } => {
-            println!("Cloning {}", remote);
+            println!("Cloning {remote}");
         }
         Commands::Diff {
             mut base,
@@ -136,22 +136,22 @@
             );
         }
         Commands::Push { remote } => {
-            println!("Pushing to {}", remote);
+            println!("Pushing to {remote}");
         }
         Commands::Add { path } => {
-            println!("Adding {:?}", path);
+            println!("Adding {path:?}");
         }
         Commands::Stash(stash) => {
             let stash_cmd = stash.command.unwrap_or(StashCommands::Push(stash.push));
             match stash_cmd {
                 StashCommands::Push(push) => {
-                    println!("Pushing {:?}", push);
+                    println!("Pushing {push:?}");
                 }
                 StashCommands::Pop { stash } => {
-                    println!("Popping {:?}", stash);
+                    println!("Popping {stash:?}");
                 }
                 StashCommands::Apply { stash } => {
-                    println!("Applying {:?}", stash);
+                    println!("Applying {stash:?}");
                 }
             }
         }
diff --git a/examples/git.md b/examples/git.md
index de01a44..d90b2e8 100644
--- a/examples/git.md
+++ b/examples/git.md
@@ -17,7 +17,7 @@
   help   Print this message or the help of the given subcommand(s)
 
 Options:
-  -h, --help  Print help information
+  -h, --help  Print help
 
 $ git help
 A fictional versioning CLI
@@ -33,7 +33,7 @@
   help   Print this message or the help of the given subcommand(s)
 
 Options:
-  -h, --help  Print help information
+  -h, --help  Print help
 
 $ git help add
 adds things
@@ -44,7 +44,7 @@
   <PATH>...  Stuff to add
 
 Options:
-  -h, --help  Print help information
+  -h, --help  Print help
 
 ```
 
@@ -60,7 +60,7 @@
   <PATH>...  Stuff to add
 
 Options:
-  -h, --help  Print help information
+  -h, --help  Print help
 
 $ git add Cargo.toml Cargo.lock
 Adding ["Cargo.toml", "Cargo.lock"]
@@ -81,14 +81,14 @@
 
 Options:
   -m, --message <MESSAGE>  
-  -h, --help               Print help information
+  -h, --help               Print help
 
 $ git stash push -h
 Usage: git[EXE] stash push [OPTIONS]
 
 Options:
   -m, --message <MESSAGE>  
-  -h, --help               Print help information
+  -h, --help               Print help
 
 $ git stash pop -h
 Usage: git[EXE] stash pop [STASH]
@@ -97,7 +97,7 @@
   [STASH]  
 
 Options:
-  -h, --help  Print help information
+  -h, --help  Print help
 
 $ git stash -m "Prototype"
 Pushing Some("Prototype")
@@ -134,7 +134,7 @@
 
 Options:
       --color[=<WHEN>]  [default: auto] [possible values: always, auto, never]
-  -h, --help            Print help information
+  -h, --help            Print help
 
 $ git diff
 Diffing stage..worktree  (color=auto)
diff --git a/examples/git.rs b/examples/git.rs
index 8a2fcc7..bd05e53 100644
--- a/examples/git.rs
+++ b/examples/git.rs
@@ -86,7 +86,7 @@
             let base = base.unwrap_or("stage");
             let head = head.unwrap_or("worktree");
             let path = path.unwrap_or("");
-            println!("Diffing {}..{} {} (color={})", base, head, path, color);
+            println!("Diffing {base}..{head} {path} (color={color})");
         }
         Some(("push", sub_matches)) => {
             println!(
@@ -100,22 +100,22 @@
                 .into_iter()
                 .flatten()
                 .collect::<Vec<_>>();
-            println!("Adding {:?}", paths);
+            println!("Adding {paths:?}");
         }
         Some(("stash", sub_matches)) => {
             let stash_command = sub_matches.subcommand().unwrap_or(("push", sub_matches));
             match stash_command {
                 ("apply", sub_matches) => {
                     let stash = sub_matches.get_one::<String>("STASH");
-                    println!("Applying {:?}", stash);
+                    println!("Applying {stash:?}");
                 }
                 ("pop", sub_matches) => {
                     let stash = sub_matches.get_one::<String>("STASH");
-                    println!("Popping {:?}", stash);
+                    println!("Popping {stash:?}");
                 }
                 ("push", sub_matches) => {
                     let message = sub_matches.get_one::<String>("message");
-                    println!("Pushing {:?}", message);
+                    println!("Pushing {message:?}");
                 }
                 (name, _) => {
                     unreachable!("Unsupported subcommand `{}`", name)
@@ -128,9 +128,9 @@
                 .into_iter()
                 .flatten()
                 .collect::<Vec<_>>();
-            println!("Calling out to {:?} with {:?}", ext, args);
+            println!("Calling out to {ext:?} with {args:?}");
         }
-        _ => unreachable!(), // If all subcommands are defined above, anything else is unreachabe!()
+        _ => unreachable!(), // If all subcommands are defined above, anything else is unreachable!()
     }
 
     // Continued program logic goes here...
diff --git a/examples/multicall-busybox.md b/examples/multicall-busybox.md
index 8ee93cc..e84b263 100644
--- a/examples/multicall-busybox.md
+++ b/examples/multicall-busybox.md
@@ -34,6 +34,6 @@
 
 Options:
       --install <install>  Install hardlinks for all subcommands in path
-  -h, --help               Print help information
+  -h, --help               Print help
 
 ```
diff --git a/examples/pacman.md b/examples/pacman.md
index 73ec86f..b02cf8f 100644
--- a/examples/pacman.md
+++ b/examples/pacman.md
@@ -45,8 +45,8 @@
   help                Print this message or the help of the given subcommand(s)
 
 Options:
-  -h, --help     Print help information
-  -V, --version  Print version information
+  -h, --help     Print help
+  -V, --version  Print version
 
 $ pacman -S -h
 Synchronize packages.
@@ -59,7 +59,7 @@
 Options:
   -s, --search <search>...  search remote repositories for matching strings
   -i, --info                view package information
-  -h, --help                Print help information
+  -h, --help                Print help
 
 ```
 
@@ -67,11 +67,11 @@
 ```console
 $ pacman -S -s foo -i bar
 ? failed
-error: The argument '--search <search>...' cannot be used with '--info'
+error: the argument '--search <search>...' cannot be used with '--info'
 
 Usage: pacman[EXE] {sync|--sync|-S} --search <search>... <package>...
 
-For more information try '--help'
+For more information, try '--help'.
 
 ```
 
diff --git a/examples/pacman.rs b/examples/pacman.rs
index 12e7ffa..7ab30db 100644
--- a/examples/pacman.rs
+++ b/examples/pacman.rs
@@ -78,7 +78,7 @@
                     .map(|s| s.as_str())
                     .collect();
                 let values = packages.join(", ");
-                println!("Searching for {}...", values);
+                println!("Searching for {values}...");
                 return;
             }
 
@@ -90,18 +90,18 @@
             let values = packages.join(", ");
 
             if sync_matches.get_flag("info") {
-                println!("Retrieving info for {}...", values);
+                println!("Retrieving info for {values}...");
             } else {
-                println!("Installing {}...", values);
+                println!("Installing {values}...");
             }
         }
         Some(("query", query_matches)) => {
             if let Some(packages) = query_matches.get_many::<String>("info") {
                 let comma_sep = packages.map(|s| s.as_str()).collect::<Vec<_>>().join(", ");
-                println!("Retrieving info for {}...", comma_sep);
+                println!("Retrieving info for {comma_sep}...");
             } else if let Some(queries) = query_matches.get_many::<String>("search") {
                 let comma_sep = queries.map(|s| s.as_str()).collect::<Vec<_>>().join(", ");
-                println!("Searching Locally for {}...", comma_sep);
+                println!("Searching Locally for {comma_sep}...");
             } else {
                 println!("Displaying all locally installed packages...");
             }
diff --git a/examples/repl.rs b/examples/repl.rs
index e18fbbd..2806ac8 100644
--- a/examples/repl.rs
+++ b/examples/repl.rs
@@ -17,7 +17,7 @@
                 }
             }
             Err(err) => {
-                write!(std::io::stdout(), "{}", err).map_err(|e| e.to_string())?;
+                write!(std::io::stdout(), "{err}").map_err(|e| e.to_string())?;
                 std::io::stdout().flush().map_err(|e| e.to_string())?;
             }
         }
@@ -29,7 +29,7 @@
 fn respond(line: &str) -> Result<bool, String> {
     let args = shlex::split(line).ok_or("error: Invalid quoting")?;
     let matches = cli()
-        .try_get_matches_from(&args)
+        .try_get_matches_from(args)
         .map_err(|e| e.to_string())?;
     match matches.subcommand() {
         Some(("ping", _matches)) => {
diff --git a/examples/tutorial_builder/01_quick.md b/examples/tutorial_builder/01_quick.md
index b963151..bdba15c 100644
--- a/examples/tutorial_builder/01_quick.md
+++ b/examples/tutorial_builder/01_quick.md
@@ -14,8 +14,8 @@
 Options:
   -c, --config <FILE>  Sets a custom config file
   -d, --debug...       Turn debugging information on
-  -h, --help           Print help information
-  -V, --version        Print version information
+  -h, --help           Print help
+  -V, --version        Print version
 
 ```
 
diff --git a/examples/tutorial_builder/01_quick.rs b/examples/tutorial_builder/01_quick.rs
index 7e53fc6..8126e33 100644
--- a/examples/tutorial_builder/01_quick.rs
+++ b/examples/tutorial_builder/01_quick.rs
@@ -48,7 +48,7 @@
     // matches just as you would the top level cmd
     if let Some(matches) = matches.subcommand_matches("test") {
         // "$ myapp test" was run
-        if *matches.get_one::<bool>("list").expect("defaulted by clap") {
+        if matches.get_flag("list") {
             // "$ myapp test -l" was run
             println!("Printing testing lists...");
         } else {
diff --git a/examples/tutorial_builder/02_app_settings.md b/examples/tutorial_builder/02_app_settings.md
index 47fa61b..3ac9a95 100644
--- a/examples/tutorial_builder/02_app_settings.md
+++ b/examples/tutorial_builder/02_app_settings.md
@@ -10,8 +10,8 @@
       --one <VALUE>
           
   -h, --help
-          Print help information
+          Print help
   -V, --version
-          Print version information
+          Print version
 
 ```
diff --git a/examples/tutorial_builder/02_apps.md b/examples/tutorial_builder/02_apps.md
index 47379ce..1f8b071 100644
--- a/examples/tutorial_builder/02_apps.md
+++ b/examples/tutorial_builder/02_apps.md
@@ -7,8 +7,8 @@
 Options:
       --two <VALUE>  
       --one <VALUE>  
-  -h, --help         Print help information
-  -V, --version      Print version information
+  -h, --help         Print help
+  -V, --version      Print version
 
 $ 02_apps --version
 MyApp 1.0
diff --git a/examples/tutorial_builder/02_crate.md b/examples/tutorial_builder/02_crate.md
index 832f7f7..a0d21b3 100644
--- a/examples/tutorial_builder/02_crate.md
+++ b/examples/tutorial_builder/02_crate.md
@@ -7,8 +7,8 @@
 Options:
       --two <VALUE>  
       --one <VALUE>  
-  -h, --help         Print help information
-  -V, --version      Print version information
+  -h, --help         Print help
+  -V, --version      Print version
 
 $ 02_crate --version
 clap [..]
diff --git a/examples/tutorial_builder/03_01_flag_bool.md b/examples/tutorial_builder/03_01_flag_bool.md
index 71f6f90..feec8e0 100644
--- a/examples/tutorial_builder/03_01_flag_bool.md
+++ b/examples/tutorial_builder/03_01_flag_bool.md
@@ -6,8 +6,8 @@
 
 Options:
   -v, --verbose  
-  -h, --help     Print help information
-  -V, --version  Print version information
+  -h, --help     Print help
+  -V, --version  Print version
 
 $ 03_01_flag_bool
 verbose: false
@@ -17,10 +17,10 @@
 
 $ 03_01_flag_bool --verbose --verbose
 ? failed
-error: The argument '--verbose' was provided more than once, but cannot be used multiple times
+error: the argument '--verbose' cannot be used multiple times
 
 Usage: 03_01_flag_bool[EXE] [OPTIONS]
 
-For more information try '--help'
+For more information, try '--help'.
 
 ```
diff --git a/examples/tutorial_builder/03_01_flag_count.md b/examples/tutorial_builder/03_01_flag_count.md
index 95610a1..5e964b6 100644
--- a/examples/tutorial_builder/03_01_flag_count.md
+++ b/examples/tutorial_builder/03_01_flag_count.md
@@ -6,8 +6,8 @@
 
 Options:
   -v, --verbose...  
-  -h, --help        Print help information
-  -V, --version     Print version information
+  -h, --help        Print help
+  -V, --version     Print version
 
 $ 03_01_flag_count
 verbose: 0
diff --git a/examples/tutorial_builder/03_02_option.md b/examples/tutorial_builder/03_02_option.md
index 68dc25e..42b81fd 100644
--- a/examples/tutorial_builder/03_02_option.md
+++ b/examples/tutorial_builder/03_02_option.md
@@ -6,8 +6,8 @@
 
 Options:
   -n, --name <name>  
-  -h, --help         Print help information
-  -V, --version      Print version information
+  -h, --help         Print help
+  -V, --version      Print version
 
 $ 03_02_option
 name: None
diff --git a/examples/tutorial_builder/03_02_option_mult.md b/examples/tutorial_builder/03_02_option_mult.md
index 21af579..659748e 100644
--- a/examples/tutorial_builder/03_02_option_mult.md
+++ b/examples/tutorial_builder/03_02_option_mult.md
@@ -6,8 +6,8 @@
 
 Options:
   -n, --name <name>  
-  -h, --help         Print help information
-  -V, --version      Print version information
+  -h, --help         Print help
+  -V, --version      Print version
 
 $ 03_02_option_mult
 name: None
diff --git a/examples/tutorial_builder/03_03_positional.md b/examples/tutorial_builder/03_03_positional.md
index df54b02..d8d49f3 100644
--- a/examples/tutorial_builder/03_03_positional.md
+++ b/examples/tutorial_builder/03_03_positional.md
@@ -8,8 +8,8 @@
   [name]  
 
 Options:
-  -h, --help     Print help information
-  -V, --version  Print version information
+  -h, --help     Print help
+  -V, --version  Print version
 
 $ 03_03_positional
 name: None
diff --git a/examples/tutorial_builder/03_03_positional_mult.md b/examples/tutorial_builder/03_03_positional_mult.md
index d31acdf..174ddd9 100644
--- a/examples/tutorial_builder/03_03_positional_mult.md
+++ b/examples/tutorial_builder/03_03_positional_mult.md
@@ -8,8 +8,8 @@
   [name]...  
 
 Options:
-  -h, --help     Print help information
-  -V, --version  Print version information
+  -h, --help     Print help
+  -V, --version  Print version
 
 $ 03_03_positional_mult
 names: []
diff --git a/examples/tutorial_builder/03_04_subcommands.md b/examples/tutorial_builder/03_04_subcommands.md
index 91a4a05..7c73add 100644
--- a/examples/tutorial_builder/03_04_subcommands.md
+++ b/examples/tutorial_builder/03_04_subcommands.md
@@ -9,8 +9,8 @@
   help  Print this message or the help of the given subcommand(s)
 
 Options:
-  -h, --help     Print help information
-  -V, --version  Print version information
+  -h, --help     Print help
+  -V, --version  Print version
 
 $ 03_04_subcommands help add
 Adds files to myapp
@@ -21,8 +21,8 @@
   [NAME]  
 
 Options:
-  -h, --help     Print help information
-  -V, --version  Print version information
+  -h, --help     Print help
+  -V, --version  Print version
 
 $ 03_04_subcommands add bob
 'myapp add' was used, name is: Some("bob")
@@ -42,8 +42,8 @@
   help  Print this message or the help of the given subcommand(s)
 
 Options:
-  -h, --help     Print help information
-  -V, --version  Print version information
+  -h, --help     Print help
+  -V, --version  Print version
 
 ```
 
diff --git a/examples/tutorial_builder/03_05_default_values.md b/examples/tutorial_builder/03_05_default_values.md
index 96880f1..b62a415 100644
--- a/examples/tutorial_builder/03_05_default_values.md
+++ b/examples/tutorial_builder/03_05_default_values.md
@@ -8,8 +8,8 @@
   [PORT]  [default: 2020]
 
 Options:
-  -h, --help     Print help information
-  -V, --version  Print version information
+  -h, --help     Print help
+  -V, --version  Print version
 
 $ 03_05_default_values
 port: 2020
diff --git a/examples/tutorial_builder/04_01_enum.md b/examples/tutorial_builder/04_01_enum.md
index 7f1a0d1..ec4c0ae 100644
--- a/examples/tutorial_builder/04_01_enum.md
+++ b/examples/tutorial_builder/04_01_enum.md
@@ -14,10 +14,10 @@
 
 Options:
   -h, --help
-          Print help information (use `-h` for a summary)
+          Print help (see a summary with '-h')
 
   -V, --version
-          Print version information
+          Print version
 
 $ 04_01_enum -h
 A simple to use, efficient, and full-featured Command Line Argument Parser
@@ -28,8 +28,8 @@
   <MODE>  What mode to run the program in [possible values: fast, slow]
 
 Options:
-  -h, --help     Print help information (use `--help` for more detail)
-  -V, --version  Print version information
+  -h, --help     Print help (see more with '--help')
+  -V, --version  Print version
 
 $ 04_01_enum fast
 Hare
@@ -39,9 +39,9 @@
 
 $ 04_01_enum medium
 ? failed
-error: 'medium' isn't a valid value for '<MODE>'
+error: invalid value 'medium' for '<MODE>'
   [possible values: fast, slow]
 
-For more information try '--help'
+For more information, try '--help'.
 
 ```
diff --git a/examples/tutorial_builder/04_01_enum.rs b/examples/tutorial_builder/04_01_enum.rs
index a8b0e68..1afa018 100644
--- a/examples/tutorial_builder/04_01_enum.rs
+++ b/examples/tutorial_builder/04_01_enum.rs
@@ -38,7 +38,7 @@
                 return Ok(*variant);
             }
         }
-        Err(format!("Invalid variant: {}", s))
+        Err(format!("invalid variant: {}", s))
     }
 }
 
diff --git a/examples/tutorial_builder/04_01_possible.md b/examples/tutorial_builder/04_01_possible.md
index 22a81fe..fa2c835 100644
--- a/examples/tutorial_builder/04_01_possible.md
+++ b/examples/tutorial_builder/04_01_possible.md
@@ -8,8 +8,8 @@
   <MODE>  What mode to run the program in [possible values: fast, slow]
 
 Options:
-  -h, --help     Print help information
-  -V, --version  Print version information
+  -h, --help     Print help
+  -V, --version  Print version
 
 $ 04_01_possible fast
 Hare
@@ -19,9 +19,9 @@
 
 $ 04_01_possible medium
 ? failed
-error: 'medium' isn't a valid value for '<MODE>'
+error: invalid value 'medium' for '<MODE>'
   [possible values: fast, slow]
 
-For more information try '--help'
+For more information, try '--help'.
 
 ```
diff --git a/examples/tutorial_builder/04_02_parse.md b/examples/tutorial_builder/04_02_parse.md
index e91f5dd..af03e95 100644
--- a/examples/tutorial_builder/04_02_parse.md
+++ b/examples/tutorial_builder/04_02_parse.md
@@ -8,22 +8,22 @@
   <PORT>  Network port to use
 
 Options:
-  -h, --help     Print help information
-  -V, --version  Print version information
+  -h, --help     Print help
+  -V, --version  Print version
 
 $ 04_02_parse 22
 PORT = 22
 
 $ 04_02_parse foobar
 ? failed
-error: Invalid value 'foobar' for '<PORT>': invalid digit found in string
+error: invalid value 'foobar' for '<PORT>': invalid digit found in string
 
-For more information try '--help'
+For more information, try '--help'.
 
 $ 04_02_parse_derive 0
 ? failed
-error: Invalid value '0' for '<PORT>': 0 is not in 1..=65535
+error: invalid value '0' for '<PORT>': 0 is not in 1..=65535
 
-For more information try '--help'
+For more information, try '--help'.
 
 ```
diff --git a/examples/tutorial_builder/04_02_validate.md b/examples/tutorial_builder/04_02_validate.md
index b62328e..949072b 100644
--- a/examples/tutorial_builder/04_02_validate.md
+++ b/examples/tutorial_builder/04_02_validate.md
@@ -8,22 +8,22 @@
   <PORT>  Network port to use
 
 Options:
-  -h, --help     Print help information
-  -V, --version  Print version information
+  -h, --help     Print help
+  -V, --version  Print version
 
 $ 04_02_validate 22
 PORT = 22
 
 $ 04_02_validate foobar
 ? failed
-error: Invalid value 'foobar' for '<PORT>': `foobar` isn't a port number
+error: invalid value 'foobar' for '<PORT>': `foobar` isn't a port number
 
-For more information try '--help'
+For more information, try '--help'.
 
 $ 04_02_validate 0
 ? failed
-error: Invalid value '0' for '<PORT>': Port not in range 1-65535
+error: invalid value '0' for '<PORT>': port not in range 1-65535
 
-For more information try '--help'
+For more information, try '--help'.
 
 ```
diff --git a/examples/tutorial_builder/04_02_validate.rs b/examples/tutorial_builder/04_02_validate.rs
index ea2f32e..4690e8e 100644
--- a/examples/tutorial_builder/04_02_validate.rs
+++ b/examples/tutorial_builder/04_02_validate.rs
@@ -28,7 +28,7 @@
         Ok(port as u16)
     } else {
         Err(format!(
-            "Port not in range {}-{}",
+            "port not in range {}-{}",
             PORT_RANGE.start(),
             PORT_RANGE.end()
         ))
diff --git a/examples/tutorial_builder/04_03_relations.md b/examples/tutorial_builder/04_03_relations.md
index cdca193..dd0c35a 100644
--- a/examples/tutorial_builder/04_03_relations.md
+++ b/examples/tutorial_builder/04_03_relations.md
@@ -14,37 +14,37 @@
       --patch              auto inc patch
       --spec-in <SPEC_IN>  some special input argument
   -c <CONFIG>              
-  -h, --help               Print help information
-  -V, --version            Print version information
+  -h, --help               Print help
+  -V, --version            Print version
 
 $ 04_03_relations
 ? failed
-error: The following required arguments were not provided:
+error: the following required arguments were not provided:
   <--set-ver <VER>|--major|--minor|--patch>
 
 Usage: 04_03_relations[EXE] <--set-ver <VER>|--major|--minor|--patch> [INPUT_FILE]
 
-For more information try '--help'
+For more information, try '--help'.
 
 $ 04_03_relations --major
 Version: 2.2.3
 
 $ 04_03_relations --major --minor
 ? failed
-error: The argument '--major' cannot be used with '--minor'
+error: the argument '--major' cannot be used with '--minor'
 
 Usage: 04_03_relations[EXE] <--set-ver <VER>|--major|--minor|--patch> [INPUT_FILE]
 
-For more information try '--help'
+For more information, try '--help'.
 
 $ 04_03_relations --major -c config.toml
 ? failed
-error: The following required arguments were not provided:
+error: the following required arguments were not provided:
   <INPUT_FILE|--spec-in <SPEC_IN>>
 
 Usage: 04_03_relations[EXE] -c <CONFIG> <--set-ver <VER>|--major|--minor|--patch> <INPUT_FILE|--spec-in <SPEC_IN>>
 
-For more information try '--help'
+For more information, try '--help'.
 
 $ 04_03_relations --major -c config.toml --spec-in input.txt
 Version: 2.2.3
diff --git a/examples/tutorial_builder/04_04_custom.md b/examples/tutorial_builder/04_04_custom.md
index 64e38b5..0a83eb9 100644
--- a/examples/tutorial_builder/04_04_custom.md
+++ b/examples/tutorial_builder/04_04_custom.md
@@ -14,8 +14,8 @@
       --patch              auto inc patch
       --spec-in <SPEC_IN>  some special input argument
   -c <CONFIG>              
-  -h, --help               Print help information
-  -V, --version            Print version information
+  -h, --help               Print help
+  -V, --version            Print version
 
 $ 04_04_custom
 ? failed
@@ -23,7 +23,7 @@
 
 Usage: 04_04_custom[EXE] [OPTIONS] [INPUT_FILE]
 
-For more information try '--help'
+For more information, try '--help'.
 
 $ 04_04_custom --major
 Version: 2.2.3
@@ -34,7 +34,7 @@
 
 Usage: 04_04_custom[EXE] [OPTIONS] [INPUT_FILE]
 
-For more information try '--help'
+For more information, try '--help'.
 
 $ 04_04_custom --major -c config.toml
 ? failed
@@ -43,7 +43,7 @@
 
 Usage: 04_04_custom[EXE] [OPTIONS] [INPUT_FILE]
 
-For more information try '--help'
+For more information, try '--help'.
 
 $ 04_04_custom --major -c config.toml --spec-in input.txt
 Version: 2.2.3
diff --git a/examples/tutorial_derive/01_quick.md b/examples/tutorial_derive/01_quick.md
index 1d97584..21bbfe1 100644
--- a/examples/tutorial_derive/01_quick.md
+++ b/examples/tutorial_derive/01_quick.md
@@ -14,8 +14,8 @@
 Options:
   -c, --config <FILE>  Sets a custom config file
   -d, --debug...       Turn debugging information on
-  -h, --help           Print help information
-  -V, --version        Print version information
+  -h, --help           Print help
+  -V, --version        Print version
 
 ```
 
diff --git a/examples/tutorial_derive/01_quick.rs b/examples/tutorial_derive/01_quick.rs
index 960e7ea..0edcd25 100644
--- a/examples/tutorial_derive/01_quick.rs
+++ b/examples/tutorial_derive/01_quick.rs
@@ -35,7 +35,7 @@
 
     // You can check the value provided by positional arguments, or option arguments
     if let Some(name) = cli.name.as_deref() {
-        println!("Value for name: {}", name);
+        println!("Value for name: {name}");
     }
 
     if let Some(config_path) = cli.config.as_deref() {
diff --git a/examples/tutorial_derive/02_app_settings.md b/examples/tutorial_derive/02_app_settings.md
index fa21fda..90da3ae 100644
--- a/examples/tutorial_derive/02_app_settings.md
+++ b/examples/tutorial_derive/02_app_settings.md
@@ -10,8 +10,8 @@
       --one <ONE>
           
   -h, --help
-          Print help information
+          Print help
   -V, --version
-          Print version information
+          Print version
 
 ```
diff --git a/examples/tutorial_derive/02_apps.md b/examples/tutorial_derive/02_apps.md
index 373d6a5..b5ae114 100644
--- a/examples/tutorial_derive/02_apps.md
+++ b/examples/tutorial_derive/02_apps.md
@@ -7,8 +7,8 @@
 Options:
       --two <TWO>  
       --one <ONE>  
-  -h, --help       Print help information
-  -V, --version    Print version information
+  -h, --help       Print help
+  -V, --version    Print version
 
 $ 02_apps_derive --version
 MyApp 1.0
diff --git a/examples/tutorial_derive/02_crate.md b/examples/tutorial_derive/02_crate.md
index 001ccad..3f64460 100644
--- a/examples/tutorial_derive/02_crate.md
+++ b/examples/tutorial_derive/02_crate.md
@@ -7,8 +7,8 @@
 Options:
       --two <TWO>  
       --one <ONE>  
-  -h, --help       Print help information
-  -V, --version    Print version information
+  -h, --help       Print help
+  -V, --version    Print version
 
 $ 02_crate_derive --version
 clap [..]
diff --git a/examples/tutorial_derive/03_01_flag_bool.md b/examples/tutorial_derive/03_01_flag_bool.md
index 83f57fa..9762260 100644
--- a/examples/tutorial_derive/03_01_flag_bool.md
+++ b/examples/tutorial_derive/03_01_flag_bool.md
@@ -6,8 +6,8 @@
 
 Options:
   -v, --verbose  
-  -h, --help     Print help information
-  -V, --version  Print version information
+  -h, --help     Print help
+  -V, --version  Print version
 
 $ 03_01_flag_bool_derive
 verbose: false
@@ -17,10 +17,10 @@
 
 $ 03_01_flag_bool_derive --verbose --verbose
 ? failed
-error: The argument '--verbose' was provided more than once, but cannot be used multiple times
+error: the argument '--verbose' cannot be used multiple times
 
 Usage: 03_01_flag_bool_derive[EXE] [OPTIONS]
 
-For more information try '--help'
+For more information, try '--help'.
 
 ```
diff --git a/examples/tutorial_derive/03_01_flag_count.md b/examples/tutorial_derive/03_01_flag_count.md
index 53834ee..56ef9ca 100644
--- a/examples/tutorial_derive/03_01_flag_count.md
+++ b/examples/tutorial_derive/03_01_flag_count.md
@@ -6,8 +6,8 @@
 
 Options:
   -v, --verbose...  
-  -h, --help        Print help information
-  -V, --version     Print version information
+  -h, --help        Print help
+  -V, --version     Print version
 
 $ 03_01_flag_count_derive
 verbose: 0
diff --git a/examples/tutorial_derive/03_02_option.md b/examples/tutorial_derive/03_02_option.md
index d1acf39..24e272a 100644
--- a/examples/tutorial_derive/03_02_option.md
+++ b/examples/tutorial_derive/03_02_option.md
@@ -6,8 +6,8 @@
 
 Options:
   -n, --name <NAME>  
-  -h, --help         Print help information
-  -V, --version      Print version information
+  -h, --help         Print help
+  -V, --version      Print version
 
 $ 03_02_option_derive
 name: None
diff --git a/examples/tutorial_derive/03_02_option_mult.md b/examples/tutorial_derive/03_02_option_mult.md
index b1969e7..cd2fe13 100644
--- a/examples/tutorial_derive/03_02_option_mult.md
+++ b/examples/tutorial_derive/03_02_option_mult.md
@@ -6,8 +6,8 @@
 
 Options:
   -n, --name <NAME>  
-  -h, --help         Print help information
-  -V, --version      Print version information
+  -h, --help         Print help
+  -V, --version      Print version
 
 $ 03_02_option_mult_derive
 name: []
diff --git a/examples/tutorial_derive/03_03_positional.md b/examples/tutorial_derive/03_03_positional.md
index 6ca99ae..9437c24 100644
--- a/examples/tutorial_derive/03_03_positional.md
+++ b/examples/tutorial_derive/03_03_positional.md
@@ -8,8 +8,8 @@
   [NAME]  
 
 Options:
-  -h, --help     Print help information
-  -V, --version  Print version information
+  -h, --help     Print help
+  -V, --version  Print version
 
 $ 03_03_positional_derive
 name: None
diff --git a/examples/tutorial_derive/03_03_positional_mult.md b/examples/tutorial_derive/03_03_positional_mult.md
index deec722..8f295e0 100644
--- a/examples/tutorial_derive/03_03_positional_mult.md
+++ b/examples/tutorial_derive/03_03_positional_mult.md
@@ -8,8 +8,8 @@
   [NAME]...  
 
 Options:
-  -h, --help     Print help information
-  -V, --version  Print version information
+  -h, --help     Print help
+  -V, --version  Print version
 
 $ 03_03_positional_mult_derive
 name: []
diff --git a/examples/tutorial_derive/03_04_subcommands.md b/examples/tutorial_derive/03_04_subcommands.md
index 3e95a68..1fbac8f 100644
--- a/examples/tutorial_derive/03_04_subcommands.md
+++ b/examples/tutorial_derive/03_04_subcommands.md
@@ -9,8 +9,8 @@
   help  Print this message or the help of the given subcommand(s)
 
 Options:
-  -h, --help     Print help information
-  -V, --version  Print version information
+  -h, --help     Print help
+  -V, --version  Print version
 
 $ 03_04_subcommands_derive help add
 Adds files to myapp
@@ -21,8 +21,8 @@
   [NAME]  
 
 Options:
-  -h, --help     Print help information
-  -V, --version  Print version information
+  -h, --help     Print help
+  -V, --version  Print version
 
 $ 03_04_subcommands_derive add bob
 'myapp add' was used, name is: Some("bob")
@@ -42,8 +42,8 @@
   help  Print this message or the help of the given subcommand(s)
 
 Options:
-  -h, --help     Print help information
-  -V, --version  Print version information
+  -h, --help     Print help
+  -V, --version  Print version
 
 ```
 
diff --git a/examples/tutorial_derive/03_04_subcommands.rs b/examples/tutorial_derive/03_04_subcommands.rs
index 279a5ff..da7c644 100644
--- a/examples/tutorial_derive/03_04_subcommands.rs
+++ b/examples/tutorial_derive/03_04_subcommands.rs
@@ -21,7 +21,7 @@
     // matches just as you would the top level cmd
     match &cli.command {
         Commands::Add { name } => {
-            println!("'myapp add' was used, name is: {:?}", name)
+            println!("'myapp add' was used, name is: {name:?}")
         }
     }
 }
diff --git a/examples/tutorial_derive/03_04_subcommands_alt.rs b/examples/tutorial_derive/03_04_subcommands_alt.rs
index 8b70dba..80b0ec6 100644
--- a/examples/tutorial_derive/03_04_subcommands_alt.rs
+++ b/examples/tutorial_derive/03_04_subcommands_alt.rs
@@ -11,11 +11,11 @@
 #[derive(Subcommand)]
 enum Commands {
     /// Adds files to myapp
-    Add(Add),
+    Add(AddArgs),
 }
 
 #[derive(Args)]
-struct Add {
+struct AddArgs {
     name: Option<String>,
 }
 
diff --git a/examples/tutorial_derive/03_05_default_values.md b/examples/tutorial_derive/03_05_default_values.md
index 194f54f..994cb33 100644
--- a/examples/tutorial_derive/03_05_default_values.md
+++ b/examples/tutorial_derive/03_05_default_values.md
@@ -8,8 +8,8 @@
   [PORT]  [default: 2020]
 
 Options:
-  -h, --help     Print help information
-  -V, --version  Print version information
+  -h, --help     Print help
+  -V, --version  Print version
 
 $ 03_05_default_values_derive
 port: 2020
diff --git a/examples/tutorial_derive/04_01_enum.md b/examples/tutorial_derive/04_01_enum.md
index d208c8f..89db08c 100644
--- a/examples/tutorial_derive/04_01_enum.md
+++ b/examples/tutorial_derive/04_01_enum.md
@@ -14,10 +14,10 @@
 
 Options:
   -h, --help
-          Print help information (use `-h` for a summary)
+          Print help (see a summary with '-h')
 
   -V, --version
-          Print version information
+          Print version
 
 $ 04_01_enum_derive -h
 A simple to use, efficient, and full-featured Command Line Argument Parser
@@ -28,8 +28,8 @@
   <MODE>  What mode to run the program in [possible values: fast, slow]
 
 Options:
-  -h, --help     Print help information (use `--help` for more detail)
-  -V, --version  Print version information
+  -h, --help     Print help (see more with '--help')
+  -V, --version  Print version
 
 $ 04_01_enum_derive fast
 Hare
@@ -39,9 +39,9 @@
 
 $ 04_01_enum_derive medium
 ? failed
-error: 'medium' isn't a valid value for '<MODE>'
+error: invalid value 'medium' for '<MODE>'
   [possible values: fast, slow]
 
-For more information try '--help'
+For more information, try '--help'.
 
 ```
diff --git a/examples/tutorial_derive/04_02_parse.md b/examples/tutorial_derive/04_02_parse.md
index df7537a..573b43c 100644
--- a/examples/tutorial_derive/04_02_parse.md
+++ b/examples/tutorial_derive/04_02_parse.md
@@ -8,22 +8,22 @@
   <PORT>  Network port to use
 
 Options:
-  -h, --help     Print help information
-  -V, --version  Print version information
+  -h, --help     Print help
+  -V, --version  Print version
 
 $ 04_02_parse_derive 22
 PORT = 22
 
 $ 04_02_parse_derive foobar
 ? failed
-error: Invalid value 'foobar' for '<PORT>': invalid digit found in string
+error: invalid value 'foobar' for '<PORT>': invalid digit found in string
 
-For more information try '--help'
+For more information, try '--help'.
 
 $ 04_02_parse_derive 0
 ? failed
-error: Invalid value '0' for '<PORT>': 0 is not in 1..=65535
+error: invalid value '0' for '<PORT>': 0 is not in 1..=65535
 
-For more information try '--help'
+For more information, try '--help'.
 
 ```
diff --git a/examples/tutorial_derive/04_02_validate.md b/examples/tutorial_derive/04_02_validate.md
index 87bf265..f8835fd 100644
--- a/examples/tutorial_derive/04_02_validate.md
+++ b/examples/tutorial_derive/04_02_validate.md
@@ -8,22 +8,22 @@
   <PORT>  Network port to use
 
 Options:
-  -h, --help     Print help information
-  -V, --version  Print version information
+  -h, --help     Print help
+  -V, --version  Print version
 
 $ 04_02_validate_derive 22
 PORT = 22
 
 $ 04_02_validate_derive foobar
 ? failed
-error: Invalid value 'foobar' for '<PORT>': `foobar` isn't a port number
+error: invalid value 'foobar' for '<PORT>': `foobar` isn't a port number
 
-For more information try '--help'
+For more information, try '--help'.
 
 $ 04_02_validate_derive 0
 ? failed
-error: Invalid value '0' for '<PORT>': Port not in range 1-65535
+error: invalid value '0' for '<PORT>': port not in range 1-65535
 
-For more information try '--help'
+For more information, try '--help'.
 
 ```
diff --git a/examples/tutorial_derive/04_02_validate.rs b/examples/tutorial_derive/04_02_validate.rs
index 2b81ef2..3391d5b 100644
--- a/examples/tutorial_derive/04_02_validate.rs
+++ b/examples/tutorial_derive/04_02_validate.rs
@@ -21,12 +21,12 @@
 fn port_in_range(s: &str) -> Result<u16, String> {
     let port: usize = s
         .parse()
-        .map_err(|_| format!("`{}` isn't a port number", s))?;
+        .map_err(|_| format!("`{s}` isn't a port number"))?;
     if PORT_RANGE.contains(&port) {
         Ok(port as u16)
     } else {
         Err(format!(
-            "Port not in range {}-{}",
+            "port not in range {}-{}",
             PORT_RANGE.start(),
             PORT_RANGE.end()
         ))
diff --git a/examples/tutorial_derive/04_03_relations.md b/examples/tutorial_derive/04_03_relations.md
index 4770334..6eafb9f 100644
--- a/examples/tutorial_derive/04_03_relations.md
+++ b/examples/tutorial_derive/04_03_relations.md
@@ -14,37 +14,37 @@
       --patch              auto inc patch
       --spec-in <SPEC_IN>  some special input argument
   -c <CONFIG>              
-  -h, --help               Print help information
-  -V, --version            Print version information
+  -h, --help               Print help
+  -V, --version            Print version
 
 $ 04_03_relations_derive
 ? failed
-error: The following required arguments were not provided:
+error: the following required arguments were not provided:
   <--set-ver <VER>|--major|--minor|--patch>
 
 Usage: 04_03_relations_derive[EXE] <--set-ver <VER>|--major|--minor|--patch> [INPUT_FILE]
 
-For more information try '--help'
+For more information, try '--help'.
 
 $ 04_03_relations_derive --major
 Version: 2.2.3
 
 $ 04_03_relations_derive --major --minor
 ? failed
-error: The argument '--major' cannot be used with '--minor'
+error: the argument '--major' cannot be used with '--minor'
 
 Usage: 04_03_relations_derive[EXE] <--set-ver <VER>|--major|--minor|--patch> [INPUT_FILE]
 
-For more information try '--help'
+For more information, try '--help'.
 
 $ 04_03_relations_derive --major -c config.toml
 ? failed
-error: The following required arguments were not provided:
+error: the following required arguments were not provided:
   <INPUT_FILE|--spec-in <SPEC_IN>>
 
 Usage: 04_03_relations_derive[EXE] -c <CONFIG> <--set-ver <VER>|--major|--minor|--patch> <INPUT_FILE|--spec-in <SPEC_IN>>
 
-For more information try '--help'
+For more information, try '--help'.
 
 $ 04_03_relations_derive --major -c config.toml --spec-in input.txt
 Version: 2.2.3
diff --git a/examples/tutorial_derive/04_03_relations.rs b/examples/tutorial_derive/04_03_relations.rs
index e366095..cbe491d 100644
--- a/examples/tutorial_derive/04_03_relations.rs
+++ b/examples/tutorial_derive/04_03_relations.rs
@@ -56,10 +56,10 @@
             (_, _, true) => patch += 1,
             _ => unreachable!(),
         };
-        format!("{}.{}.{}", major, minor, patch)
+        format!("{major}.{minor}.{patch}")
     };
 
-    println!("Version: {}", version);
+    println!("Version: {version}");
 
     // Check for usage of -c
     if let Some(config) = cli.config.as_deref() {
@@ -67,6 +67,6 @@
             .input_file
             .as_deref()
             .unwrap_or_else(|| cli.spec_in.as_deref().unwrap());
-        println!("Doing work using input {} and config {}", input, config);
+        println!("Doing work using input {input} and config {config}");
     }
 }
diff --git a/examples/tutorial_derive/04_04_custom.md b/examples/tutorial_derive/04_04_custom.md
index a68a914..c601e9f 100644
--- a/examples/tutorial_derive/04_04_custom.md
+++ b/examples/tutorial_derive/04_04_custom.md
@@ -14,8 +14,8 @@
       --patch              auto inc patch
       --spec-in <SPEC_IN>  some special input argument
   -c <CONFIG>              
-  -h, --help               Print help information
-  -V, --version            Print version information
+  -h, --help               Print help
+  -V, --version            Print version
 
 $ 04_04_custom_derive
 ? failed
@@ -23,7 +23,7 @@
 
 Usage: clap [OPTIONS] [INPUT_FILE]
 
-For more information try '--help'
+For more information, try '--help'.
 
 $ 04_04_custom_derive --major
 Version: 2.2.3
@@ -34,7 +34,7 @@
 
 Usage: clap [OPTIONS] [INPUT_FILE]
 
-For more information try '--help'
+For more information, try '--help'.
 
 $ 04_04_custom_derive --major -c config.toml
 ? failed
@@ -43,7 +43,7 @@
 
 Usage: clap [OPTIONS] [INPUT_FILE]
 
-For more information try '--help'
+For more information, try '--help'.
 
 $ 04_04_custom_derive --major -c config.toml --spec-in input.txt
 Version: 2.2.3
diff --git a/examples/tutorial_derive/04_04_custom.rs b/examples/tutorial_derive/04_04_custom.rs
index cbc460f..a84b5ed 100644
--- a/examples/tutorial_derive/04_04_custom.rs
+++ b/examples/tutorial_derive/04_04_custom.rs
@@ -66,10 +66,10 @@
                 .exit();
             }
         };
-        format!("{}.{}.{}", major, minor, patch)
+        format!("{major}.{minor}.{patch}")
     };
 
-    println!("Version: {}", version);
+    println!("Version: {version}");
 
     // Check for usage of -c
     if let Some(config) = cli.config.as_deref() {
@@ -86,6 +86,6 @@
                 )
                 .exit()
             });
-        println!("Doing work using input {} and config {}", input, config);
+        println!("Doing work using input {input} and config {config}");
     }
 }
diff --git a/examples/typed-derive.md b/examples/typed-derive.md
index 713594d..bf7a56a 100644
--- a/examples/typed-derive.md
+++ b/examples/typed-derive.md
@@ -13,7 +13,7 @@
   -D <DEFINES>                 Hand-written parser for tuples
       --port <PORT>            Support for discrete numbers [default: 22] [possible values: 22, 80]
       --log-level <LOG_LEVEL>  Support enums from a foreign crate that don't implement `ValueEnum` [default: info] [possible values: info, debug, info, warn, error]
-  -h, --help                   Print help information
+  -h, --help                   Print help
 
 ```
 
@@ -24,9 +24,9 @@
 
 $ typed-derive -O plaid
 ? failed
-error: Invalid value 'plaid' for '-O <OPTIMIZATION>': invalid digit found in string
+error: invalid value 'plaid' for '-O <OPTIMIZATION>': invalid digit found in string
 
-For more information try '--help'
+For more information, try '--help'.
 
 ```
 
@@ -44,9 +44,9 @@
 
 $ typed-derive --bind localhost
 ? failed
-error: Invalid value 'localhost' for '--bind <BIND>': invalid IP address syntax
+error: invalid value 'localhost' for '--bind <BIND>': invalid IP address syntax
 
-For more information try '--help'
+For more information, try '--help'.
 
 ```
 
@@ -57,9 +57,9 @@
 
 $ typed-derive --sleep forever
 ? failed
-error: Invalid value 'forever' for '--sleep <SLEEP>': expected number at 0
+error: invalid value 'forever' for '--sleep <SLEEP>': expected number at 0
 
-For more information try '--help'
+For more information, try '--help'.
 
 ```
 
@@ -70,15 +70,15 @@
 
 $ typed-derive -D Foo
 ? failed
-error: Invalid value 'Foo' for '-D <DEFINES>': invalid KEY=value: no `=` found in `Foo`
+error: invalid value 'Foo' for '-D <DEFINES>': invalid KEY=value: no `=` found in `Foo`
 
-For more information try '--help'
+For more information, try '--help'.
 
 $ typed-derive -D Foo=Bar
 ? failed
-error: Invalid value 'Foo=Bar' for '-D <DEFINES>': invalid digit found in string
+error: invalid value 'Foo=Bar' for '-D <DEFINES>': invalid digit found in string
 
-For more information try '--help'
+For more information, try '--help'.
 
 ```
 
@@ -92,17 +92,17 @@
 
 $ typed-derive --port
 ? failed
-error: The argument '--port <PORT>' requires a value but none was supplied
+error: a value is required for '--port <PORT>' but none was supplied
   [possible values: 22, 80]
 
-For more information try '--help'
+For more information, try '--help'.
 
 $ typed-derive --port 3000
 ? failed
-error: '3000' isn't a valid value for '--port <PORT>'
+error: invalid value '3000' for '--port <PORT>'
   [possible values: 22, 80]
 
-For more information try '--help'
+For more information, try '--help'.
 
 ```
 
@@ -116,16 +116,16 @@
 
 $ typed-derive --log-level
 ? failed
-error: The argument '--log-level <LOG_LEVEL>' requires a value but none was supplied
+error: a value is required for '--log-level <LOG_LEVEL>' but none was supplied
   [possible values: info, debug, info, warn, error]
 
-For more information try '--help'
+For more information, try '--help'.
 
 $ typed-derive --log-level critical
 ? failed
-error: 'critical' isn't a valid value for '--log-level <LOG_LEVEL>'
+error: invalid value 'critical' for '--log-level <LOG_LEVEL>'
   [possible values: info, debug, info, warn, error]
 
-For more information try '--help'
+For more information, try '--help'.
 
 ```
diff --git a/examples/typed-derive.rs b/examples/typed-derive.rs
index bdf8a58..8d7a84e 100644
--- a/examples/typed-derive.rs
+++ b/examples/typed-derive.rs
@@ -54,7 +54,7 @@
 {
     let pos = s
         .find('=')
-        .ok_or_else(|| format!("invalid KEY=value: no `=` found in `{}`", s))?;
+        .ok_or_else(|| format!("invalid KEY=value: no `=` found in `{s}`"))?;
     Ok((s[..pos].parse()?, s[pos + 1..].parse()?))
 }
 
@@ -98,5 +98,5 @@
 
 fn main() {
     let args = Args::parse();
-    println!("{:?}", args);
+    println!("{args:?}");
 }
diff --git a/src/_derive/_tutorial.rs b/src/_derive/_tutorial.rs
index eb95c87..f3f55c3 100644
--- a/src/_derive/_tutorial.rs
+++ b/src/_derive/_tutorial.rs
@@ -75,7 +75,7 @@
 #![doc = include_str!("../../examples/tutorial_derive/03_03_positional.md")]
 //!
 //! Note that the default [`ArgAction`][crate::ArgAction] is [`Set`][crate::ArgAction::Set].  To
-//! accept multiple values, use [`Append`][crate::ArgAction::Append]:
+//! accept multiple values, use [`Append`][crate::ArgAction::Append] via `Vec`:
 //! ```rust
 #![doc = include_str!("../../examples/tutorial_derive/03_03_positional_mult.rs")]
 //! ```
@@ -98,7 +98,7 @@
 #![doc = include_str!("../../examples/tutorial_derive/03_02_option.md")]
 //!
 //! Note that the default [`ArgAction`][crate::ArgAction] is [`Set`][crate::ArgAction::Set].  To
-//! accept multiple occurrences, use [`Append`][crate::ArgAction::Append]:
+//! accept multiple occurrences, use [`Append`][crate::ArgAction::Append] via `Vec`:
 //! ```rust
 #![doc = include_str!("../../examples/tutorial_derive/03_02_option_mult.rs")]
 //! ```
diff --git a/src/_derive/mod.rs b/src/_derive/mod.rs
index b09cdf6..a92b7c8 100644
--- a/src/_derive/mod.rs
+++ b/src/_derive/mod.rs
@@ -232,7 +232,8 @@
 //!   - Without `<expr>`: fills the field with `Default::default()`
 //! - `default_value = <str>`: [`Arg::default_value`][crate::Arg::default_value] and [`Arg::required(false)`][crate::Arg::required]
 //! - `default_value_t [= <expr>]`: [`Arg::default_value`][crate::Arg::default_value] and [`Arg::required(false)`][crate::Arg::required]
-//!   - Requires `std::fmt::Display` or `#[arg(value_enum)]`
+//!   - Requires `std::fmt::Display` that roundtrips correctly with the
+//!     [`Arg::value_parser`][crate::Arg::value_parser] or `#[arg(value_enum)]`
 //!   - Without `<expr>`, relies on `Default::default()`
 //! - `default_values_t = <expr>`: [`Arg::default_values`][crate::Arg::default_values] and [`Arg::required(false)`][crate::Arg::required]
 //!   - Requires field arg to be of type `Vec<T>` and `T` to implement `std::fmt::Display` or `#[arg(value_enum)]`
diff --git a/src/_features.rs b/src/_features.rs
index 10d6163..2f551e7 100644
--- a/src/_features.rs
+++ b/src/_features.rs
@@ -26,5 +26,4 @@
 //! **Warning:** These may contain breaking changes between minor releases.
 //!
 //! * **unstable-replace**: Enable [`Command::replace`](https://github.com/clap-rs/clap/issues/2836)
-//! * **unstable-grouped**: Enable [`ArgMatches::grouped_values_of`](https://github.com/clap-rs/clap/issues/2924)
 //! * **unstable-v5**: Preview features which will be stable on the v5.0 release
diff --git a/src/_tutorial.rs b/src/_tutorial.rs
index 3f0a833..4605ec9 100644
--- a/src/_tutorial.rs
+++ b/src/_tutorial.rs
@@ -75,7 +75,7 @@
 //! ```
 #![doc = include_str!("../examples/tutorial_builder/03_03_positional.md")]
 //!
-//! Note that the default [`ArgAction`][crate::ArgAction]` is [`Set`][crate::ArgAction::Set].  To
+//! Note that the default [`ArgAction`][crate::ArgAction] is [`Set`][crate::ArgAction::Set].  To
 //! accept multiple values, use [`Append`][crate::ArgAction::Append]:
 //! ```rust
 #![doc = include_str!("../examples/tutorial_builder/03_03_positional_mult.rs")]
@@ -94,7 +94,7 @@
 //! ```
 #![doc = include_str!("../examples/tutorial_builder/03_02_option.md")]
 //!
-//! Note that the default [`ArgAction`][crate::ArgAction]` is [`Set`][crate::ArgAction::Set].  To
+//! Note that the default [`ArgAction`][crate::ArgAction] is [`Set`][crate::ArgAction::Set].  To
 //! accept multiple occurrences, use [`Append`][crate::ArgAction::Append]:
 //! ```rust
 #![doc = include_str!("../examples/tutorial_builder/03_02_option_mult.rs")]
diff --git a/src/builder/action.rs b/src/builder/action.rs
index 01d1f07..9739f88 100644
--- a/src/builder/action.rs
+++ b/src/builder/action.rs
@@ -99,15 +99,15 @@
     /// let matches = cmd.clone().try_get_matches_from(["mycmd", "--flag"]).unwrap();
     /// assert!(matches.contains_id("flag"));
     /// assert_eq!(
-    ///     matches.get_one::<bool>("flag").copied(),
-    ///     Some(true)
+    ///     matches.get_flag("flag"),
+    ///     true
     /// );
     ///
     /// let matches = cmd.try_get_matches_from(["mycmd"]).unwrap();
     /// assert!(matches.contains_id("flag"));
     /// assert_eq!(
-    ///     matches.get_one::<bool>("flag").copied(),
-    ///     Some(false)
+    ///     matches.get_flag("flag"),
+    ///     false
     /// );
     /// ```
     ///
@@ -172,15 +172,15 @@
     /// let matches = cmd.clone().try_get_matches_from(["mycmd", "--flag"]).unwrap();
     /// assert!(matches.contains_id("flag"));
     /// assert_eq!(
-    ///     matches.get_one::<bool>("flag").copied(),
-    ///     Some(false)
+    ///     matches.get_flag("flag"),
+    ///     false
     /// );
     ///
     /// let matches = cmd.try_get_matches_from(["mycmd"]).unwrap();
     /// assert!(matches.contains_id("flag"));
     /// assert_eq!(
-    ///     matches.get_one::<bool>("flag").copied(),
-    ///     Some(true)
+    ///     matches.get_flag("flag"),
+    ///     true
     /// );
     /// ```
     SetFalse,
diff --git a/src/builder/arg.rs b/src/builder/arg.rs
index 17db059..bf898cb 100644
--- a/src/builder/arg.rs
+++ b/src/builder/arg.rs
@@ -286,7 +286,7 @@
     ///             .get_matches_from(vec![
     ///                 "prog", "--do-tests"
     ///             ]);
-    /// assert_eq!(*m.get_one::<bool>("test").expect("defaulted by clap"), true);
+    /// assert_eq!(m.get_flag("test"), true);
     /// ```
     #[must_use]
     pub fn aliases(mut self, names: impl IntoIterator<Item = impl Into<Str>>) -> Self {
@@ -314,7 +314,7 @@
     ///             .get_matches_from(vec![
     ///                 "prog", "-s"
     ///             ]);
-    /// assert_eq!(*m.get_one::<bool>("test").expect("defaulted by clap"), true);
+    /// assert_eq!(m.get_flag("test"), true);
     /// ```
     #[must_use]
     pub fn short_aliases(mut self, names: impl IntoIterator<Item = char>) -> Self {
@@ -399,7 +399,7 @@
     ///        .get_matches_from(vec![
     ///             "prog", "--awesome"
     ///         ]);
-    /// assert_eq!(*m.get_one::<bool>("test").expect("defaulted by clap"), true);
+    /// assert_eq!(m.get_flag("test"), true);
     /// ```
     /// [`Command::aliases`]: Arg::aliases()
     #[must_use]
@@ -425,7 +425,7 @@
     ///        .get_matches_from(vec![
     ///             "prog", "-t"
     ///         ]);
-    /// assert_eq!(*m.get_one::<bool>("test").expect("defaulted by clap"), true);
+    /// assert_eq!(m.get_flag("test"), true);
     /// ```
     #[must_use]
     pub fn visible_short_aliases(mut self, names: impl IntoIterator<Item = char>) -> Self {
@@ -807,7 +807,7 @@
     ///
     /// assert_eq!(m.subcommand_name(), Some("do-stuff"));
     /// let sub_m = m.subcommand_matches("do-stuff").unwrap();
-    /// assert_eq!(*sub_m.get_one::<bool>("verb").expect("defaulted by clap"), true);
+    /// assert_eq!(sub_m.get_flag("verb"), true);
     /// ```
     ///
     /// [`Subcommand`]: crate::Subcommand
@@ -1900,9 +1900,9 @@
     ///         "prog"
     ///     ]);
     ///
-    /// assert!(*m.get_one::<bool>("true_flag").unwrap());
-    /// assert!(!*m.get_one::<bool>("false_flag").unwrap());
-    /// assert!(!*m.get_one::<bool>("absent_flag").unwrap());
+    /// assert!(m.get_flag("true_flag"));
+    /// assert!(!m.get_flag("false_flag"));
+    /// assert!(!m.get_flag("absent_flag"));
     /// ```
     ///
     /// In this example, we show the variable coming from an option on the CLI:
@@ -2111,7 +2111,8 @@
     ///
     /// Args with a lower value will be displayed first in the help message. This is helpful when
     /// one would like to emphasise frequently used args, or prioritize those towards the top of
-    /// the list. Args with duplicate display orders will be displayed in alphabetical order.
+    /// the list. Args with duplicate display orders will be displayed in the order they are
+    /// defined.
     ///
     /// **NOTE:** The default is 999 for all arguments.
     ///
@@ -3639,10 +3640,10 @@
     ///         "prog", "-f", "-d", "-c"]);
     ///             //    ^~~~~~~~~~~~^~~~~ flag is overridden by color
     ///
-    /// assert!(*m.get_one::<bool>("color").unwrap());
-    /// assert!(*m.get_one::<bool>("debug").unwrap()); // even though flag conflicts with debug, it's as if flag
+    /// assert!(m.get_flag("color"));
+    /// assert!(m.get_flag("debug")); // even though flag conflicts with debug, it's as if flag
     ///                                 // was never used because it was overridden with color
-    /// assert!(!*m.get_one::<bool>("flag").unwrap());
+    /// assert!(!m.get_flag("flag"));
     /// ```
     #[must_use]
     pub fn overrides_with(mut self, arg_id: impl IntoResettable<Id>) -> Self {
@@ -3678,11 +3679,11 @@
     ///         "prog", "-f", "-d", "-c"]);
     ///             //    ^~~~~~^~~~~~~~~ flag and debug are overridden by color
     ///
-    /// assert!(*m.get_one::<bool>("color").unwrap()); // even though flag conflicts with color, it's as if flag
+    /// assert!(m.get_flag("color")); // even though flag conflicts with color, it's as if flag
     ///                                 // and debug were never used because they were overridden
     ///                                 // with color
-    /// assert!(!*m.get_one::<bool>("debug").unwrap());
-    /// assert!(!*m.get_one::<bool>("flag").unwrap());
+    /// assert!(!m.get_flag("debug"));
+    /// assert!(!m.get_flag("flag"));
     /// ```
     #[must_use]
     pub fn overrides_with_all(mut self, names: impl IntoIterator<Item = impl Into<Id>>) -> Self {
@@ -3858,6 +3859,13 @@
         self.val_delim
     }
 
+    /// Get the value terminator for this argument. The value_terminator is a value
+    /// that terminates parsing of multi-valued arguments.
+    #[inline]
+    pub fn get_value_terminator(&self) -> Option<&Str> {
+        self.terminator.as_ref()
+    }
+
     /// Get the index of this argument, if any
     #[inline]
     pub fn get_index(&self) -> Option<usize> {
@@ -4115,7 +4123,7 @@
             if self.val_names.len() > 1 {
                 self.val_names
                     .iter()
-                    .map(|n| format!("<{}>", n))
+                    .map(|n| format!("<{n}>"))
                     .collect::<Vec<_>>()
                     .join(delim)
             } else {
@@ -4179,7 +4187,7 @@
         styled
     }
 
-    /// Write the values such as <name1> <name2>
+    /// Write the values such as `<name1> <name2>`
     fn render_arg_val(&self, required: bool) -> String {
         let mut rendered = String::new();
 
@@ -4199,9 +4207,9 @@
         debug_assert!(self.is_takes_value_set());
         for (n, val_name) in val_names.iter().enumerate() {
             let arg_name = if self.is_positional() && (num_vals.min_values() == 0 || !required) {
-                format!("[{}]", val_name)
+                format!("[{val_name}]")
             } else {
-                format!("<{}>", val_name)
+                format!("<{val_name}>")
             };
 
             if n != 0 {
diff --git a/src/builder/arg_settings.rs b/src/builder/arg_settings.rs
index 0f63e43..b8bc069 100644
--- a/src/builder/arg_settings.rs
+++ b/src/builder/arg_settings.rs
@@ -113,7 +113,7 @@
         assert!(m.is_required_set());
 
         let m = m.unset_setting(ArgSettings::Required);
-        assert!(!m.is_required_set(), "{:#?}", m);
+        assert!(!m.is_required_set(), "{m:#?}");
     }
 
     #[test]
@@ -138,8 +138,8 @@
         assert!(m.is_last_set());
 
         let m = m.unset_setting(ArgSettings::Required | ArgSettings::Hidden | ArgSettings::Last);
-        assert!(!m.is_required_set(), "{:#?}", m);
-        assert!(!m.is_hide_set(), "{:#?}", m);
-        assert!(!m.is_last_set(), "{:#?}", m);
+        assert!(!m.is_required_set(), "{m:#?}");
+        assert!(!m.is_hide_set(), "{m:#?}");
+        assert!(!m.is_last_set(), "{m:#?}");
     }
 }
diff --git a/src/builder/command.rs b/src/builder/command.rs
index 203e677..72a68dc 100644
--- a/src/builder/command.rs
+++ b/src/builder/command.rs
@@ -243,7 +243,7 @@
         let a = self
             .args
             .remove_by_name(id)
-            .unwrap_or_else(|| panic!("Argument `{}` is undefined", id));
+            .unwrap_or_else(|| panic!("Argument `{id}` is undefined"));
 
         self.args.push(f(a));
         self
@@ -287,7 +287,7 @@
         let subcmd = if let Some(idx) = pos {
             self.subcommands.remove(idx)
         } else {
-            panic!("Command `{}` is undefined", name)
+            panic!("Command `{name}` is undefined")
         };
 
         self.subcommands.push(f(subcmd));
@@ -449,7 +449,7 @@
     ///
     /// fn main() {
     ///     let m = cmd().get_matches_from(vec!["foo", "-b"]);
-    ///     println!("{}", *m.get_one::<bool>("bar").expect("defaulted by clap"));
+    ///     println!("{}", m.get_flag("bar"));
     /// }
     /// ```
     pub fn debug_assert(mut self) {
@@ -487,7 +487,7 @@
     /// [`Command::try_get_matches_from_mut`]: Command::try_get_matches_from_mut()
     #[inline]
     pub fn get_matches(self) -> ArgMatches {
-        self.get_matches_from(&mut env::args_os())
+        self.get_matches_from(env::args_os())
     }
 
     /// Parse [`env::args_os`], exiting on failure.
@@ -545,7 +545,7 @@
     #[inline]
     pub fn try_get_matches(self) -> ClapResult<ArgMatches> {
         // Start the parsing
-        self.try_get_matches_from(&mut env::args_os())
+        self.try_get_matches_from(env::args_os())
     }
 
     /// Parse the specified arguments, exiting on failure.
@@ -822,7 +822,7 @@
         let mut styled = StyledStr::new();
         let usage = Usage::new(self);
         write_help(&mut styled, self, &usage, false);
-        ok!(write!(w, "{}", styled));
+        ok!(write!(w, "{styled}"));
         w.flush()
     }
 
@@ -837,7 +837,7 @@
         let mut styled = StyledStr::new();
         let usage = Usage::new(self);
         write_help(&mut styled, self, &usage, true);
-        ok!(write!(w, "{}", styled));
+        ok!(write!(w, "{styled}"));
         w.flush()
     }
 
@@ -963,7 +963,7 @@
     /// assert!(r.is_ok(), "unexpected error: {:?}", r);
     /// let m = r.unwrap();
     /// assert_eq!(m.get_one::<String>("config").unwrap(), "file");
-    /// assert!(*m.get_one::<bool>("f").expect("defaulted"));
+    /// assert!(m.get_flag("f"));
     /// assert_eq!(m.get_one::<String>("stuff"), None);
     /// ```
     #[inline]
@@ -1744,7 +1744,7 @@
     /// Valid tags are:
     ///
     ///   * `{name}`                - Display name for the (sub-)command.
-    ///   * `{bin}`                 - Binary name.
+    ///   * `{bin}`                 - Binary name.(deprecated)
     ///   * `{version}`             - Version number.
     ///   * `{author}`              - Author information.
     ///   * `{author-with-newline}` - Author followed by `\n`.
@@ -1760,7 +1760,7 @@
     ///   * `{options}`             - Help for options.
     ///   * `{positionals}`         - Help for positional arguments.
     ///   * `{subcommands}`         - Help for subcommands.
-    ///   * `{tag}`                 - Standard tab sized used within clap
+    ///   * `{tab}`                 - Standard tab sized used within clap
     ///   * `{after-help}`          - Help from [`Command::after_help`] or [`Command::after_long_help`].
     ///   * `{before-help}`         - Help from [`Command::before_help`] or [`Command::before_long_help`].
     ///
@@ -1772,7 +1772,7 @@
     /// # use clap::Command;
     /// Command::new("myprog")
     ///     .version("1.0")
-    ///     .help_template("{bin} ({version}) - {usage}")
+    ///     .help_template("{name} ({version}) - {usage}")
     /// # ;
     /// ```
     ///
@@ -1943,8 +1943,8 @@
     ///     .replace("--save-all", &["--save-context", "--save-runtime"])
     ///     .get_matches_from(vec!["cmd", "--save-all"]);
     ///
-    /// assert!(*m.get_one::<bool>("save-context").expect("defaulted by clap"));
-    /// assert!(*m.get_one::<bool>("save-runtime").expect("defaulted by clap"));
+    /// assert!(m.get_flag("save-context"));
+    /// assert!(m.get_flag("save-runtime"));
     /// ```
     ///
     /// This can also be used with options, for example if our application with
@@ -1969,8 +1969,8 @@
     ///     .replace("--save-all", &["--save-context", "--save-runtime", "--format=json"])
     ///     .get_matches_from(vec!["cmd", "--save-all"]);
     ///
-    /// assert!(*m.get_one::<bool>("save-context").expect("defaulted by clap"));
-    /// assert!(*m.get_one::<bool>("save-runtime").expect("defaulted by clap"));
+    /// assert!(m.get_flag("save-context"));
+    /// assert!(m.get_flag("save-runtime"));
     /// assert_eq!(m.get_one::<String>("format").unwrap(), "json");
     /// ```
     ///
@@ -2191,7 +2191,7 @@
     ///
     /// assert_eq!(matches.subcommand_name().unwrap(), "sync");
     /// let sync_matches = matches.subcommand_matches("sync").unwrap();
-    /// assert!(*sync_matches.get_one::<bool>("search").expect("defaulted by clap"));
+    /// assert!(sync_matches.get_flag("search"));
     /// ```
     /// [`Arg::short`]: Arg::short()
     #[must_use]
@@ -2228,7 +2228,7 @@
     ///
     /// assert_eq!(matches.subcommand_name().unwrap(), "sync");
     /// let sync_matches = matches.subcommand_matches("sync").unwrap();
-    /// assert!(*sync_matches.get_one::<bool>("search").expect("defaulted by clap"));
+    /// assert!(sync_matches.get_flag("search"));
     /// ```
     ///
     /// [`Arg::long`]: Arg::long()
@@ -2599,7 +2599,7 @@
     /// Set the placement of this subcommand within the help.
     ///
     /// Subcommands with a lower value will be displayed first in the help message.  Subcommands
-    /// with duplicate display orders will be displayed in alphabetical order.
+    /// with duplicate display orders will be displayed in order they are defined.
     ///
     /// This is helpful when one would like to emphasize frequently used subcommands, or prioritize
     /// those towards the top of the list.
@@ -2641,8 +2641,8 @@
     ///     alpha   Some help and text
     ///
     /// Options:
-    ///     -h, --help       Print help information
-    ///     -V, --version    Print version information
+    ///     -h, --help       Print help
+    ///     -V, --version    Print version
     /// ```
     #[inline]
     #[must_use]
@@ -3105,8 +3105,8 @@
     ///     sub1
     ///
     /// Options:
-    ///     -h, --help       Print help information
-    ///     -V, --version    Print version information
+    ///     -h, --help       Print help
+    ///     -V, --version    Print version
     /// ```
     ///
     /// but usage of `subcommand_value_name`
@@ -3132,8 +3132,8 @@
     ///     sub1
     ///
     /// Options:
-    ///     -h, --help       Print help information
-    ///     -V, --version    Print version information
+    ///     -h, --help       Print help
+    ///     -V, --version    Print version
     /// ```
     #[must_use]
     pub fn subcommand_value_name(mut self, value_name: impl IntoResettable<Str>) -> Self {
@@ -3169,8 +3169,8 @@
     ///     sub1
     ///
     /// Options:
-    ///     -h, --help       Print help information
-    ///     -V, --version    Print version information
+    ///     -h, --help       Print help
+    ///     -V, --version    Print version
     /// ```
     ///
     /// but usage of `subcommand_help_heading`
@@ -3196,8 +3196,8 @@
     ///     sub1
     ///
     /// Options:
-    ///     -h, --help       Print help information
-    ///     -V, --version    Print version information
+    ///     -h, --help       Print help
+    ///     -V, --version    Print version
     /// ```
     #[must_use]
     pub fn subcommand_help_heading(mut self, heading: impl IntoResettable<Str>) -> Self {
@@ -3947,22 +3947,22 @@
         sc_names.push_str(sc.name.as_str());
         let mut flag_subcmd = false;
         if let Some(l) = sc.get_long_flag() {
-            write!(sc_names, "|--{}", l).unwrap();
+            write!(sc_names, "|--{l}").unwrap();
             flag_subcmd = true;
         }
         if let Some(s) = sc.get_short_flag() {
-            write!(sc_names, "|-{}", s).unwrap();
+            write!(sc_names, "|-{s}").unwrap();
             flag_subcmd = true;
         }
 
         if flag_subcmd {
-            sc_names = format!("{{{}}}", sc_names);
+            sc_names = format!("{{{sc_names}}}");
         }
 
         let usage_name = self
             .bin_name
             .as_ref()
-            .map(|bin_name| format!("{}{}{}", bin_name, mid_string, sc_names))
+            .map(|bin_name| format!("{bin_name}{mid_string}{sc_names}"))
             .unwrap_or(sc_names);
         sc.usage_name = Some(usage_name);
 
@@ -4044,19 +4044,19 @@
                     sc_names.push_str(sc.name.as_str());
                     let mut flag_subcmd = false;
                     if let Some(l) = sc.get_long_flag() {
-                        write!(sc_names, "|--{}", l).unwrap();
+                        write!(sc_names, "|--{l}").unwrap();
                         flag_subcmd = true;
                     }
                     if let Some(s) = sc.get_short_flag() {
-                        write!(sc_names, "|-{}", s).unwrap();
+                        write!(sc_names, "|-{s}").unwrap();
                         flag_subcmd = true;
                     }
 
                     if flag_subcmd {
-                        sc_names = format!("{{{}}}", sc_names);
+                        sc_names = format!("{{{sc_names}}}");
                     }
 
-                    let usage_name = format!("{}{}{}", self_bin_name, mid_string, sc_names);
+                    let usage_name = format!("{self_bin_name}{mid_string}{sc_names}");
                     debug!(
                         "Command::_build_bin_names:iter: Setting usage_name of {} to {:?}",
                         sc.name, usage_name
@@ -4243,10 +4243,10 @@
                 .action(ArgAction::Help);
             if self.long_help_exists {
                 arg = arg
-                    .help("Print help information (use `--help` for more detail)")
-                    .long_help("Print help information (use `-h` for a summary)");
+                    .help("Print help (see more with '--help')")
+                    .long_help("Print help (see a summary with '-h')");
             } else {
-                arg = arg.help("Print help information");
+                arg = arg.help("Print help");
             }
             // Avoiding `arg_internal` to not be sensitive to `next_help_heading` /
             // `next_display_order`
@@ -4258,7 +4258,7 @@
                 .short('V')
                 .long("version")
                 .action(ArgAction::Version)
-                .help("Print version information");
+                .help("Print version");
             // Avoiding `arg_internal` to not be sensitive to `next_help_heading` /
             // `next_display_order`
             self.args.push(arg);
@@ -4334,7 +4334,7 @@
                 .unwrap_or_default()
         };
         let display_name = self.get_display_name().unwrap_or_else(|| self.get_name());
-        format!("{} {}\n", display_name, ver)
+        format!("{display_name} {ver}\n")
     }
 
     pub(crate) fn format_group(&self, g: &Id) -> StyledStr {
@@ -4593,12 +4593,14 @@
         // specified by the user is sent through. If hide_short_help is not included,
         // then items specified with hidden_short_help will also be hidden.
         let should_long = |v: &Arg| {
-            v.get_long_help().is_some()
-                || v.is_hide_long_help_set()
-                || v.is_hide_short_help_set()
-                || v.get_possible_values()
-                    .iter()
-                    .any(PossibleValue::should_show_help)
+            !v.is_hide_set()
+                && (v.get_long_help().is_some()
+                    || v.is_hide_long_help_set()
+                    || v.is_hide_short_help_set()
+                    || (!v.is_hide_possible_values_set()
+                        && v.get_possible_values()
+                            .iter()
+                            .any(PossibleValue::should_show_help)))
         };
 
         // Subcommands aren't checked because we prefer short help for them, deferring to
diff --git a/src/builder/debug_asserts.rs b/src/builder/debug_asserts.rs
index dff70e3..86e3677 100644
--- a/src/builder/debug_asserts.rs
+++ b/src/builder/debug_asserts.rs
@@ -40,20 +40,20 @@
 
     for sc in cmd.get_subcommands() {
         if let Some(s) = sc.get_short_flag().as_ref() {
-            short_flags.push(Flag::Command(format!("-{}", s), sc.get_name()));
+            short_flags.push(Flag::Command(format!("-{s}"), sc.get_name()));
         }
 
         for short_alias in sc.get_all_short_flag_aliases() {
-            short_flags.push(Flag::Command(format!("-{}", short_alias), sc.get_name()));
+            short_flags.push(Flag::Command(format!("-{short_alias}"), sc.get_name()));
         }
 
         if let Some(l) = sc.get_long_flag().as_ref() {
             assert!(!l.starts_with('-'), "Command {}: long_flag {:?} must not start with a `-`, that will be handled by the parser", sc.get_name(), l);
-            long_flags.push(Flag::Command(format!("--{}", l), sc.get_name()));
+            long_flags.push(Flag::Command(format!("--{l}"), sc.get_name()));
         }
 
         for long_alias in sc.get_all_long_flag_aliases() {
-            long_flags.push(Flag::Command(format!("--{}", long_alias), sc.get_name()));
+            long_flags.push(Flag::Command(format!("--{long_alias}"), sc.get_name()));
         }
     }
 
@@ -68,26 +68,20 @@
         );
 
         if let Some(s) = arg.get_short() {
-            short_flags.push(Flag::Arg(format!("-{}", s), arg.get_id().as_str()));
+            short_flags.push(Flag::Arg(format!("-{s}"), arg.get_id().as_str()));
         }
 
         for (short_alias, _) in &arg.short_aliases {
-            short_flags.push(Flag::Arg(
-                format!("-{}", short_alias),
-                arg.get_id().as_str(),
-            ));
+            short_flags.push(Flag::Arg(format!("-{short_alias}"), arg.get_id().as_str()));
         }
 
         if let Some(l) = arg.get_long() {
             assert!(!l.starts_with('-'), "Argument {}: long {:?} must not start with a `-`, that will be handled by the parser", arg.get_id(), l);
-            long_flags.push(Flag::Arg(format!("--{}", l), arg.get_id().as_str()));
+            long_flags.push(Flag::Arg(format!("--{l}"), arg.get_id().as_str()));
         }
 
         for (long_alias, _) in &arg.aliases {
-            long_flags.push(Flag::Arg(
-                format!("--{}", long_alias),
-                arg.get_id().as_str(),
-            ));
+            long_flags.push(Flag::Arg(format!("--{long_alias}"), arg.get_id().as_str()));
         }
 
         // Name conflicts
@@ -359,6 +353,13 @@
             cmd.get_name(),
             "`{unified}` template variable was removed in clap3, use `{options}` instead"
         );
+        #[cfg(feature = "unstable-v5")]
+        assert!(
+            !help_template.to_string().contains("{bin}"),
+            "Command {}: {}",
+            cmd.get_name(),
+            "`{bin}` template variable was removed in clap5, use `{name}` instead"
+        )
     }
 
     cmd._panic_on_missing_help(cmd.is_help_expected_set());
@@ -422,19 +423,16 @@
     for (one, two) in find_duplicates(flags) {
         match (one, two) {
             (Command(flag, one), Command(_, another)) if one != another => panic!(
-                "the '{}' {} flag is specified for both '{}' and '{}' subcommands",
-                flag, short_or_long, one, another
+                "the '{flag}' {short_or_long} flag is specified for both '{one}' and '{another}' subcommands"
             ),
 
             (Arg(flag, one), Arg(_, another)) if one != another => panic!(
-                "{} option names must be unique, but '{}' is in use by both '{}' and '{}'",
-                short_or_long, flag, one, another
+                "{short_or_long} option names must be unique, but '{flag}' is in use by both '{one}' and '{another}'"
             ),
 
             (Arg(flag, arg), Command(_, sub)) | (Command(flag, sub), Arg(_, arg)) => panic!(
-                "the '{}' {} flag for the '{}' argument conflicts with the short flag \
-                     for '{}' subcommand",
-                flag, short_or_long, arg, sub
+                "the '{flag}' {short_or_long} flag for the '{arg}' argument conflicts with the short flag \
+                     for '{sub}' subcommand"
             ),
 
             _ => {}
@@ -522,10 +520,8 @@
 
     assert!(
         highest_idx == num_p,
-        "Found positional argument whose index is {} but there \
-             are only {} positional arguments defined",
-        highest_idx,
-        num_p
+        "Found positional argument whose index is {highest_idx} but there \
+             are only {num_p} positional arguments defined",
     );
 
     for arg in cmd.get_arguments() {
diff --git a/src/builder/range.rs b/src/builder/range.rs
index cc2890b..6ecf053 100644
--- a/src/builder/range.rs
+++ b/src/builder/range.rs
@@ -92,7 +92,7 @@
     }
 
     pub(crate) fn num_values(&self) -> Option<usize> {
-        self.is_fixed().then(|| self.start_inclusive)
+        self.is_fixed().then_some(self.start_inclusive)
     }
 
     pub(crate) fn accepts_more(&self, current: usize) -> bool {
@@ -183,7 +183,7 @@
 
 impl std::fmt::Debug for ValueRange {
     fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        write!(f, "{}", self)
+        write!(f, "{self}")
     }
 }
 
diff --git a/src/builder/resettable.rs b/src/builder/resettable.rs
index 0176d39..e0b82b1 100644
--- a/src/builder/resettable.rs
+++ b/src/builder/resettable.rs
@@ -10,6 +10,24 @@
 use crate::builder::ValueRange;
 
 /// Clearable builder value
+///
+/// This allows a builder function to both accept any value that can [`Into::into`] `T` (like
+/// `&str` into `OsStr`) as well as `None` to reset it to the default.  This is needed to
+/// workaround a limitation where you can't have a function argument that is `impl Into<Option<T>>`
+/// where `T` is `impl Into<S>` accept `None` as its type is ambiguous.
+///
+/// # Example
+///
+/// ```rust
+/// # use clap::Command;
+/// # use clap::Arg;
+/// fn common() -> Command {
+///     Command::new("cli")
+///         .arg(Arg::new("input").short('i').long("input"))
+/// }
+/// let mut command = common();
+/// command.mut_arg("input", |arg| arg.short(None));
+/// ```
 #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
 pub enum Resettable<T> {
     /// Overwrite builder value
diff --git a/src/builder/str.rs b/src/builder/str.rs
index c6689d3..be69c3f 100644
--- a/src/builder/str.rs
+++ b/src/builder/str.rs
@@ -246,7 +246,10 @@
         }
 
         pub(crate) fn into_string(self) -> String {
-            self.as_str().to_owned()
+            match self {
+                Self::Static(s) => s.to_owned(),
+                Self::Owned(s) => s.into(),
+            }
         }
     }
 }
diff --git a/src/builder/styled_str.rs b/src/builder/styled_str.rs
index ecd05a3..d36329d 100644
--- a/src/builder/styled_str.rs
+++ b/src/builder/styled_str.rs
@@ -1,4 +1,7 @@
 /// Terminal-styling container
+///
+/// For now, this is the same as a [`Str`][crate::builder::Str].  This exists to reserve space in
+/// the API for exposing terminal styling.
 #[derive(Clone, Default, Debug, PartialEq, Eq)]
 pub struct StyledStr {
     #[cfg(feature = "color")]
diff --git a/src/builder/value_hint.rs b/src/builder/value_hint.rs
index 812d5d8..ee286b1 100644
--- a/src/builder/value_hint.rs
+++ b/src/builder/value_hint.rs
@@ -89,7 +89,7 @@
             "hostname" => ValueHint::Hostname,
             "url" => ValueHint::Url,
             "emailaddress" => ValueHint::EmailAddress,
-            _ => return Err(format!("unknown ValueHint: `{}`", s)),
+            _ => return Err(format!("unknown ValueHint: `{s}`")),
         })
     }
 }
diff --git a/src/builder/value_parser.rs b/src/builder/value_parser.rs
index 4681857..191e8ae 100644
--- a/src/builder/value_parser.rs
+++ b/src/builder/value_parser.rs
@@ -2351,18 +2351,15 @@
 /// assert_eq!(format!("{:?}", parser), "ValueParser::os_string");
 /// let parser = clap::value_parser!(std::path::PathBuf);
 /// assert_eq!(format!("{:?}", parser), "ValueParser::path_buf");
-/// let parser = clap::value_parser!(u16).range(3000..);
-/// assert_eq!(format!("{:?}", parser), "RangedI64ValueParser { bounds: (Included(3000), Included(65535)), target: PhantomData }");
-/// let parser = clap::value_parser!(u64).range(3000..);
-/// assert_eq!(format!("{:?}", parser), "RangedU64ValueParser { bounds: (Included(3000), Unbounded), target: PhantomData }");
+/// clap::value_parser!(u16).range(3000..);
+/// clap::value_parser!(u64).range(3000..);
 ///
 /// // FromStr types
 /// let parser = clap::value_parser!(usize);
 /// assert_eq!(format!("{:?}", parser), "_AnonymousValueParser(ValueParser::other(usize))");
 ///
 /// // ValueEnum types
-/// let parser = clap::value_parser!(ColorChoice);
-/// assert_eq!(format!("{:?}", parser), "EnumValueParser(PhantomData)");
+/// clap::value_parser!(ColorChoice);
 /// ```
 #[macro_export]
 macro_rules! value_parser {
diff --git a/src/derive.rs b/src/derive.rs
index a5df2ed..98bb012 100644
--- a/src/derive.rs
+++ b/src/derive.rs
@@ -69,7 +69,7 @@
 /// impl From<ArgMatches> for Context {
 ///     fn from(m: ArgMatches) -> Self {
 ///         Context {
-///             verbose: *m.get_one::<bool>("verbose").expect("defaulted_by_clap"),
+///             verbose: m.get_flag("verbose"),
 ///             name: m.get_one::<String>("name").cloned(),
 ///         }
 ///     }
@@ -201,7 +201,7 @@
     ///    fn from(m: ArgMatches) -> Self {
     ///        Context {
     ///            name: m.get_one::<String>("name").unwrap().clone(),
-    ///            debug: *m.get_one::<bool>("debug").expect("defaulted by clap"),
+    ///            debug: m.get_flag("debug"),
     ///        }
     ///    }
     /// }
@@ -235,7 +235,7 @@
     ///    fn from(m: ArgMatches) -> Self {
     ///        Context {
     ///            name: m.get_one::<String>("name").unwrap().to_string(),
-    ///            debug: *m.get_one::<bool>("debug").expect("defaulted by clap"),
+    ///            debug: m.get_flag("debug"),
     ///        }
     ///    }
     /// }
@@ -278,7 +278,7 @@
 /// #[derive(clap::Args)]
 /// struct LogArgs {
 ///     #[arg(long, short = 'v', action = clap::ArgAction::Count)]
-///     verbose: i8,
+///     verbose: u8,
 /// }
 /// ```
 pub trait Args: FromArgMatches + Sized {
@@ -385,7 +385,7 @@
                     .matches(input, ignore_case)
             })
             .cloned()
-            .ok_or_else(|| format!("Invalid variant: {}", input))
+            .ok_or_else(|| format!("invalid variant: {input}"))
     }
 
     /// The canonical argument value.
diff --git a/src/error/format.rs b/src/error/format.rs
index 1714943..d3ce6c6 100644
--- a/src/error/format.rs
+++ b/src/error/format.rs
@@ -36,7 +36,7 @@
         } else if let Some(source) = error.inner.source.as_ref() {
             styled.none(source.to_string());
         } else {
-            styled.none("Unknown cause");
+            styled.none("unknown cause");
         }
         styled.none("\n");
         styled
@@ -44,6 +44,8 @@
 }
 
 /// Richly formatted error context
+///
+/// This follows the [rustc diagnostic style guide](https://rustc-dev-guide.rust-lang.org/diagnostics.html#suggestion-style-guide).
 #[non_exhaustive]
 #[cfg(feature = "error-context")]
 pub struct RichFormatter;
@@ -60,27 +62,44 @@
             } else if let Some(source) = error.inner.source.as_ref() {
                 styled.none(source.to_string());
             } else {
-                styled.none("Unknown cause");
+                styled.none("unknown cause");
             }
         }
 
+        let mut suggested = false;
         if let Some(valid) = error.get(ContextKind::SuggestedSubcommand) {
-            styled.none("\n\n");
-            did_you_mean(&mut styled, valid);
+            styled.none("\n");
+            if !suggested {
+                styled.none("\n");
+                suggested = true;
+            }
+            did_you_mean(&mut styled, "subcommand", valid);
         }
         if let Some(valid) = error.get(ContextKind::SuggestedArg) {
-            styled.none("\n\n");
-            did_you_mean(&mut styled, valid);
+            styled.none("\n");
+            if !suggested {
+                styled.none("\n");
+                suggested = true;
+            }
+            did_you_mean(&mut styled, "argument", valid);
         }
         if let Some(valid) = error.get(ContextKind::SuggestedValue) {
-            styled.none("\n\n");
-            did_you_mean(&mut styled, valid);
+            styled.none("\n");
+            if !suggested {
+                styled.none("\n");
+                suggested = true;
+            }
+            did_you_mean(&mut styled, "value", valid);
         }
         let suggestions = error.get(ContextKind::Suggested);
         if let Some(ContextValue::StyledStrs(suggestions)) = suggestions {
+            if !suggested {
+                styled.none("\n");
+            }
             for suggestion in suggestions {
-                styled.none("\n\n");
+                styled.none("\n");
                 styled.none(TAB);
+                styled.good("note: ");
                 styled.extend(suggestion.iter());
             }
         }
@@ -112,11 +131,11 @@
                 (invalid_arg, prior_arg)
             {
                 if ContextValue::String(invalid_arg.clone()) == *prior_arg {
-                    styled.none("The argument '");
+                    styled.none("the argument '");
                     styled.warning(invalid_arg);
-                    styled.none("' was provided more than once, but cannot be used multiple times");
+                    styled.none("' cannot be used multiple times");
                 } else {
-                    styled.none("The argument '");
+                    styled.none("the argument '");
                     styled.warning(invalid_arg);
                     styled.none("' cannot be used with");
 
@@ -147,7 +166,7 @@
         ErrorKind::NoEquals => {
             let invalid_arg = error.get(ContextKind::InvalidArg);
             if let Some(ContextValue::String(invalid_arg)) = invalid_arg {
-                styled.none("Equal sign is needed when assigning values to '");
+                styled.none("equal sign is needed when assigning values to '");
                 styled.warning(invalid_arg);
                 styled.none("'");
                 true
@@ -164,13 +183,13 @@
             ) = (invalid_arg, invalid_value)
             {
                 if invalid_value.is_empty() {
-                    styled.none("The argument '");
+                    styled.none("a value is required for '");
                     styled.warning(invalid_arg);
-                    styled.none("' requires a value but none was supplied");
+                    styled.none("' but none was supplied");
                 } else {
-                    styled.none("'");
+                    styled.none("invalid value '");
                     styled.none(invalid_value);
-                    styled.none("' isn't a valid value for '");
+                    styled.none("' for '");
                     styled.warning(invalid_arg);
                     styled.none("'");
                 }
@@ -199,9 +218,9 @@
         ErrorKind::InvalidSubcommand => {
             let invalid_sub = error.get(ContextKind::InvalidSubcommand);
             if let Some(ContextValue::String(invalid_sub)) = invalid_sub {
-                styled.none("The subcommand '");
+                styled.none("unrecognized subcommand '");
                 styled.warning(invalid_sub);
-                styled.none("' wasn't recognized");
+                styled.none("'");
                 true
             } else {
                 false
@@ -210,7 +229,7 @@
         ErrorKind::MissingRequiredArgument => {
             let invalid_arg = error.get(ContextKind::InvalidArg);
             if let Some(ContextValue::Strings(invalid_arg)) = invalid_arg {
-                styled.none("The following required arguments were not provided:");
+                styled.none("the following required arguments were not provided:");
                 for v in invalid_arg {
                     styled.none("\n");
                     styled.none(TAB);
@@ -259,11 +278,11 @@
                 Some(ContextValue::String(invalid_value)),
             ) = (invalid_arg, invalid_value)
             {
-                styled.none("The value '");
+                styled.none("unexpected value '");
                 styled.warning(invalid_value);
-                styled.none("' was provided to '");
+                styled.none("' for '");
                 styled.warning(invalid_arg);
-                styled.none("' but it wasn't expecting any more values");
+                styled.none("' found; no more were expected");
                 true
             } else {
                 false
@@ -280,11 +299,10 @@
             ) = (invalid_arg, actual_num_values, min_values)
             {
                 let were_provided = singular_or_plural(*actual_num_values as usize);
-                styled.none("The argument '");
-                styled.warning(invalid_arg);
-                styled.none("' requires at least ");
                 styled.warning(min_values.to_string());
-                styled.none(" values but only ");
+                styled.none(" more values required by '");
+                styled.warning(invalid_arg);
+                styled.none("'; only ");
                 styled.warning(actual_num_values.to_string());
                 styled.none(were_provided);
                 true
@@ -300,7 +318,7 @@
                 Some(ContextValue::String(invalid_value)),
             ) = (invalid_arg, invalid_value)
             {
-                styled.none("Invalid value '");
+                styled.none("invalid value '");
                 styled.warning(invalid_value);
                 styled.none("' for '");
                 styled.warning(invalid_arg);
@@ -326,11 +344,10 @@
             ) = (invalid_arg, actual_num_values, num_values)
             {
                 let were_provided = singular_or_plural(*actual_num_values as usize);
-                styled.none("The argument '");
-                styled.warning(invalid_arg);
-                styled.none("' requires ");
                 styled.warning(num_values.to_string());
-                styled.none(" values, but ");
+                styled.none(" values required for '");
+                styled.warning(invalid_arg);
+                styled.none("' but ");
                 styled.warning(actual_num_values.to_string());
                 styled.none(were_provided);
                 true
@@ -341,9 +358,9 @@
         ErrorKind::UnknownArgument => {
             let invalid_arg = error.get(ContextKind::InvalidArg);
             if let Some(ContextValue::String(invalid_arg)) = invalid_arg {
-                styled.none("Found argument '");
+                styled.none("unexpected argument '");
                 styled.warning(invalid_arg.to_string());
-                styled.none("' which wasn't expected, or isn't valid in this context");
+                styled.none("' found");
                 true
             } else {
                 false
@@ -400,24 +417,31 @@
 
 fn try_help(styled: &mut StyledStr, help: Option<&str>) {
     if let Some(help) = help {
-        styled.none("\n\nFor more information try '");
+        styled.none("\n\nFor more information, try '");
         styled.literal(help.to_owned());
-        styled.none("'\n");
+        styled.none("'.\n");
     } else {
         styled.none("\n");
     }
 }
 
 #[cfg(feature = "error-context")]
-fn did_you_mean(styled: &mut StyledStr, valid: &ContextValue) {
+fn did_you_mean(styled: &mut StyledStr, context: &str, valid: &ContextValue) {
     if let ContextValue::String(valid) = valid {
         styled.none(TAB);
-        styled.none("Did you mean '");
+        styled.good("note: ");
+        styled.none(context);
+        styled.none(" '");
         styled.good(valid);
-        styled.none("'?");
+        styled.none("' exists");
     } else if let ContextValue::Strings(valid) = valid {
         styled.none(TAB);
-        styled.none("Did you mean ");
+        styled.good("note: ");
+        styled.none(context);
+        if valid.len() > 1 {
+            styled.none("s");
+        }
+        styled.none(" ");
         for (i, valid) in valid.iter().enumerate() {
             if i != 0 {
                 styled.none(", ");
@@ -426,14 +450,18 @@
             styled.good(valid);
             styled.none("'");
         }
-        styled.none("?");
+        if valid.len() == 1 {
+            styled.none(" exists");
+        } else {
+            styled.none(" exist");
+        }
     }
 }
 
 fn escape(s: impl AsRef<str>) -> String {
     let s = s.as_ref();
     if s.contains(char::is_whitespace) {
-        format!("{:?}", s)
+        format!("{s:?}")
     } else {
         s.to_owned()
     }
diff --git a/src/error/kind.rs b/src/error/kind.rs
index aa316ef..1859237 100644
--- a/src/error/kind.rs
+++ b/src/error/kind.rs
@@ -82,7 +82,7 @@
     /// fn is_numeric(val: &str) -> Result<(), String> {
     ///     match val.parse::<i64>() {
     ///         Ok(..) => Ok(()),
-    ///         Err(..) => Err(String::from("Value wasn't a number!")),
+    ///         Err(..) => Err(String::from("value wasn't a number!")),
     ///     }
     /// }
     ///
@@ -316,24 +316,22 @@
     /// End-user description of the error case, where relevant
     pub fn as_str(self) -> Option<&'static str> {
         match self {
-            Self::InvalidValue => Some("One of the values isn't valid for an argument"),
-            Self::UnknownArgument => {
-                Some("Found an argument which wasn't expected or isn't valid in this context")
-            }
-            Self::InvalidSubcommand => Some("A subcommand wasn't recognized"),
-            Self::NoEquals => Some("Equal is needed when assigning values to one of the arguments"),
-            Self::ValueValidation => Some("Invalid value for one of the arguments"),
-            Self::TooManyValues => Some("An argument received an unexpected value"),
-            Self::TooFewValues => Some("An argument requires more values"),
-            Self::WrongNumberOfValues => Some("An argument received too many or too few values"),
+            Self::InvalidValue => Some("one of the values isn't valid for an argument"),
+            Self::UnknownArgument => Some("unexpected argument found"),
+            Self::InvalidSubcommand => Some("unrecognized subcommand"),
+            Self::NoEquals => Some("equal is needed when assigning values to one of the arguments"),
+            Self::ValueValidation => Some("invalid value for one of the arguments"),
+            Self::TooManyValues => Some("unexpected value for an argument found"),
+            Self::TooFewValues => Some("more values required for an argument"),
+            Self::WrongNumberOfValues => Some("too many or too few values for an argument"),
             Self::ArgumentConflict => {
-                Some("An argument cannot be used with one or more of the other specified arguments")
+                Some("an argument cannot be used with one or more of the other specified arguments")
             }
             Self::MissingRequiredArgument => {
-                Some("One or more required arguments were not provided")
+                Some("one or more required arguments were not provided")
             }
-            Self::MissingSubcommand => Some("A subcommand is required but one was not provided"),
-            Self::InvalidUtf8 => Some("Invalid UTF-8 was detected in one or more arguments"),
+            Self::MissingSubcommand => Some("a subcommand is required but one was not provided"),
+            Self::InvalidUtf8 => Some("invalid UTF-8 was detected in one or more arguments"),
             Self::DisplayHelp => None,
             Self::DisplayHelpOnMissingArgumentOrSubcommand => None,
             Self::DisplayVersion => None,
diff --git a/src/error/mod.rs b/src/error/mod.rs
index d88df46..2d8bf62 100644
--- a/src/error/mod.rs
+++ b/src/error/mod.rs
@@ -242,7 +242,10 @@
     /// ```
     pub fn print(&self) -> io::Result<()> {
         let style = self.formatted();
-        let color_when = if self.kind() == ErrorKind::DisplayHelp {
+        let color_when = if matches!(
+            self.kind(),
+            ErrorKind::DisplayHelp | ErrorKind::DisplayHelpOnMissingArgumentOrSubcommand,
+        ) {
             self.inner.color_help_when
         } else {
             self.inner.color_when
@@ -431,8 +434,9 @@
         #[cfg(feature = "error-context")]
         {
             let mut styled_suggestion = StyledStr::new();
-            styled_suggestion
-                .none("If you believe you received this message in error, try re-running with '");
+            styled_suggestion.none("to pass '");
+            styled_suggestion.warning(&subcmd);
+            styled_suggestion.none("' as a value, use '");
             styled_suggestion.good(name);
             styled_suggestion.good(" -- ");
             styled_suggestion.good(&subcmd);
@@ -659,9 +663,9 @@
             let mut suggestions = vec![];
             if suggested_trailing_arg {
                 let mut styled_suggestion = StyledStr::new();
-                styled_suggestion.none("If you tried to supply '");
+                styled_suggestion.none("to pass '");
                 styled_suggestion.warning(&arg);
-                styled_suggestion.none("' as a value rather than a flag, use '");
+                styled_suggestion.none("' as a value, use '");
                 styled_suggestion.good("-- ");
                 styled_suggestion.good(&arg);
                 styled_suggestion.none("'");
@@ -677,18 +681,18 @@
             match did_you_mean {
                 Some((flag, Some(sub))) => {
                     let mut styled_suggestion = StyledStr::new();
-                    styled_suggestion.none("Did you mean to put '");
+                    styled_suggestion.none("'");
+                    styled_suggestion.good(sub);
+                    styled_suggestion.none(" ");
                     styled_suggestion.good("--");
                     styled_suggestion.good(flag);
-                    styled_suggestion.none("' after the subcommand '");
-                    styled_suggestion.good(sub);
-                    styled_suggestion.none("'?");
+                    styled_suggestion.none("' exists");
                     suggestions.push(styled_suggestion);
                 }
                 Some((flag, None)) => {
                     err = err.insert_context_unchecked(
                         ContextKind::SuggestedArg,
-                        ContextValue::String(format!("--{}", flag)),
+                        ContextValue::String(format!("--{flag}")),
                     );
                 }
                 None => {}
@@ -714,11 +718,11 @@
         #[cfg(feature = "error-context")]
         {
             let mut styled_suggestion = StyledStr::new();
-            styled_suggestion.none("If you tried to supply '");
-            styled_suggestion.warning(&arg);
-            styled_suggestion.none("' as a subcommand, remove the '");
+            styled_suggestion.none("subcommand '");
+            styled_suggestion.good(&arg);
+            styled_suggestion.none("' exists; to use it, remove the '");
             styled_suggestion.warning("--");
-            styled_suggestion.none("' before it.");
+            styled_suggestion.none("' before it");
 
             err = err.extend_context_unchecked([
                 (ContextKind::InvalidArg, ContextValue::String(arg)),
@@ -778,7 +782,7 @@
         if let Some(backtrace) = self.inner.backtrace.as_ref() {
             ok!(writeln!(f));
             ok!(writeln!(f, "Backtrace:"));
-            ok!(writeln!(f, "{}", backtrace));
+            ok!(writeln!(f, "{backtrace}"));
         }
         Ok(())
     }
diff --git a/src/lib.rs b/src/lib.rs
index 393e1f0..ab2d9d4 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -24,7 +24,7 @@
 //!   - Leverage feature flags to keep to one active branch
 //!   - Being under [WG-CLI](https://github.com/rust-cli/team/) to increase the bus factor
 //! - We follow semver and will wait about 6-9 months between major breaking changes
-//! - We will support the last two minor Rust releases (MSRV, currently 1.60.0)
+//! - We will support the last two minor Rust releases (MSRV, currently 1.64.0)
 //!
 //! While these aspirations can be at odds with fast build times and low binary
 //! size, we will still strive to keep these reasonable for the flexibility you
diff --git a/src/macros.rs b/src/macros.rs
index e5e5a71..8addab3 100644
--- a/src/macros.rs
+++ b/src/macros.rs
@@ -17,7 +17,7 @@
 #[macro_export]
 macro_rules! crate_version {
     () => {
-        "4.0.29"
+        "4.1.8"
     };
 }
 
@@ -85,6 +85,12 @@
 
 /// Allows you to pull the name from your Cargo.toml at compile time.
 ///
+/// **NOTE:** This macro extracts the name from an environment variable `CARGO_PKG_NAME`.
+/// When the crate name is set to something different from the package name,
+/// use environment variables `CARGO_CRATE_NAME` or `CARGO_BIN_NAME`.
+/// See [the Cargo Book](https://doc.rust-lang.org/cargo/reference/environment-variables.html)
+/// for more information.
+///
 /// # Examples
 ///
 /// ```no_run
@@ -197,256 +203,238 @@
         ($arg:expr)
         --$long:ident
         $($tail:tt)*
-    ) => {
-        $crate::arg_impl! {
-            @arg
-            ({
-                debug_assert_eq!($arg.get_value_names(), None, "Flags should precede values");
-                debug_assert!(!matches!($arg.get_action(), $crate::ArgAction::Append), "Flags should precede `...`");
+    ) => {{
+        debug_assert_eq!($arg.get_value_names(), None, "Flags should precede values");
+        debug_assert!(!matches!($arg.get_action(), $crate::ArgAction::Append), "Flags should precede `...`");
 
-                let mut arg = $arg;
-                let long = $crate::arg_impl! { @string $long };
-                if arg.get_id() == "" {
-                    arg = arg.id(long);
-                }
-                let action = $crate::ArgAction::SetTrue;
-                arg
-                    .long(long)
-                    .action(action)
-            })
-            $($tail)*
+        let mut arg = $arg;
+        let long = $crate::arg_impl! { @string $long };
+        if arg.get_id() == "" {
+            arg = arg.id(long);
         }
-    };
+        let action = $crate::ArgAction::SetTrue;
+        let arg = arg
+            .long(long)
+            .action(action);
+        let arg = $crate::arg_impl! {
+            @arg (arg) $($tail)*
+        };
+        arg
+    }};
     (
         @arg
         ($arg:expr)
         --$long:literal
         $($tail:tt)*
-    ) => {
-        $crate::arg_impl! {
-            @arg
-            ({
-                debug_assert_eq!($arg.get_value_names(), None, "Flags should precede values");
-                debug_assert!(!matches!($arg.get_action(), $crate::ArgAction::Append), "Flags should precede `...`");
+    ) => {{
+        debug_assert_eq!($arg.get_value_names(), None, "Flags should precede values");
+        debug_assert!(!matches!($arg.get_action(), $crate::ArgAction::Append), "Flags should precede `...`");
 
-                let mut arg = $arg;
-                let long = $crate::arg_impl! { @string $long };
-                if arg.get_id() == "" {
-                    arg = arg.id(long);
-                }
-                let action = $crate::ArgAction::SetTrue;
-                arg
-                    .long(long)
-                    .action(action)
-            })
-            $($tail)*
+        let mut arg = $arg;
+        let long = $crate::arg_impl! { @string $long };
+        if arg.get_id() == "" {
+            arg = arg.id(long);
         }
-    };
+        let action = $crate::ArgAction::SetTrue;
+        let arg = arg
+            .long(long)
+            .action(action);
+        let arg = $crate::arg_impl! {
+            @arg (arg) $($tail)*
+        };
+        arg
+    }};
     (
         @arg
         ($arg:expr)
         -$short:ident
         $($tail:tt)*
-    ) => {
-        $crate::arg_impl! {
-            @arg
-            ({
-                debug_assert_eq!($arg.get_long(), None, "Short flags should precede long flags");
-                debug_assert_eq!($arg.get_value_names(), None, "Flags should precede values");
-                debug_assert!(!matches!($arg.get_action(), $crate::ArgAction::Append), "Flags should precede `...`");
+    ) => {{
+        debug_assert_eq!($arg.get_long(), None, "Short flags should precede long flags");
+        debug_assert_eq!($arg.get_value_names(), None, "Flags should precede values");
+        debug_assert!(!matches!($arg.get_action(), $crate::ArgAction::Append), "Flags should precede `...`");
 
-                let action = $crate::ArgAction::SetTrue;
-                $arg
-                    .short($crate::arg_impl! { @char $short })
-                    .action(action)
-            })
-            $($tail)*
-        }
-    };
+        let action = $crate::ArgAction::SetTrue;
+        let arg = $arg
+            .short($crate::arg_impl! { @char $short })
+            .action(action);
+        let arg = $crate::arg_impl! {
+            @arg (arg) $($tail)*
+        };
+        arg
+    }};
     (
         @arg
         ($arg:expr)
         -$short:literal
         $($tail:tt)*
-    ) => {
-        $crate::arg_impl! {
-            @arg
-            ({
-                debug_assert_eq!($arg.get_long(), None, "Short flags should precede long flags");
-                debug_assert_eq!($arg.get_value_names(), None, "Flags should precede values");
-                debug_assert!(!matches!($arg.get_action(), $crate::ArgAction::Append), "Flags should precede `...`");
+    ) => {{
+        debug_assert_eq!($arg.get_long(), None, "Short flags should precede long flags");
+        debug_assert_eq!($arg.get_value_names(), None, "Flags should precede values");
+        debug_assert!(!matches!($arg.get_action(), $crate::ArgAction::Append), "Flags should precede `...`");
 
-                let action = $crate::ArgAction::SetTrue;
-                $arg
-                    .short($crate::arg_impl! { @char $short })
-                    .action(action)
-            })
-            $($tail)*
-        }
-    };
+        let action = $crate::ArgAction::SetTrue;
+        let arg = $arg
+            .short($crate::arg_impl! { @char $short })
+            .action(action);
+        let arg = $crate::arg_impl! {
+            @arg (arg) $($tail)*
+        };
+        arg
+    }};
     (
         @arg
         ($arg:expr)
         <$value_name:ident>
         $($tail:tt)*
-    ) => {
-        $crate::arg_impl! {
-            @arg
-            ({
-                debug_assert!(!matches!($arg.get_action(), $crate::ArgAction::Append), "Flags should precede `...`");
-                debug_assert_eq!($arg.get_value_names(), None, "Multiple values not yet supported");
+    ) => {{
+        debug_assert!(!matches!($arg.get_action(), $crate::ArgAction::Append), "Flags should precede `...`");
+        debug_assert_eq!($arg.get_value_names(), None, "Multiple values not yet supported");
 
-                let mut arg = $arg;
+        let mut arg = $arg;
 
-                if arg.get_long().is_none() && arg.get_short().is_none() {
-                    arg = arg.required(true);
-                }
-
-                let value_name = $crate::arg_impl! { @string $value_name };
-                if arg.get_id() == "" {
-                    arg = arg.id(value_name);
-                }
-                arg
-                    .value_name(value_name)
-                    .action($crate::ArgAction::Set)
-            })
-            $($tail)*
+        if arg.get_long().is_none() && arg.get_short().is_none() {
+            arg = arg.required(true);
         }
-    };
+
+        let value_name = $crate::arg_impl! { @string $value_name };
+        if arg.get_id() == "" {
+            arg = arg.id(value_name);
+        }
+        let arg = arg
+            .value_name(value_name)
+            .action($crate::ArgAction::Set);
+        let arg = $crate::arg_impl! {
+            @arg (arg) $($tail)*
+        };
+        arg
+    }};
     (
         @arg
         ($arg:expr)
         <$value_name:literal>
         $($tail:tt)*
-    ) => {
-        $crate::arg_impl! {
-            @arg
-            ({
-                debug_assert!(!matches!($arg.get_action(), $crate::ArgAction::Append), "Flags should precede `...`");
-                debug_assert_eq!($arg.get_value_names(), None, "Multiple values not yet supported");
+    ) => {{
+        debug_assert!(!matches!($arg.get_action(), $crate::ArgAction::Append), "Flags should precede `...`");
+        debug_assert_eq!($arg.get_value_names(), None, "Multiple values not yet supported");
 
-                let mut arg = $arg;
+        let mut arg = $arg;
 
-                if arg.get_long().is_none() && arg.get_short().is_none() {
-                    arg = arg.required(true);
-                }
-
-                let value_name = $crate::arg_impl! { @string $value_name };
-                if arg.get_id() == "" {
-                    arg = arg.id(value_name);
-                }
-                arg
-                    .value_name(value_name)
-                    .action($crate::ArgAction::Set)
-            })
-            $($tail)*
+        if arg.get_long().is_none() && arg.get_short().is_none() {
+            arg = arg.required(true);
         }
-    };
+
+        let value_name = $crate::arg_impl! { @string $value_name };
+        if arg.get_id() == "" {
+            arg = arg.id(value_name);
+        }
+        let arg = arg
+            .value_name(value_name)
+            .action($crate::ArgAction::Set);
+        let arg = $crate::arg_impl! {
+            @arg (arg) $($tail)*
+        };
+        arg
+    }};
     (
         @arg
         ($arg:expr)
         [$value_name:ident]
         $($tail:tt)*
-    ) => {
-        $crate::arg_impl! {
-            @arg
-            ({
-                debug_assert!(!matches!($arg.get_action(), $crate::ArgAction::Append), "Flags should precede `...`");
-                debug_assert_eq!($arg.get_value_names(), None, "Multiple values not yet supported");
+    ) => {{
+        debug_assert!(!matches!($arg.get_action(), $crate::ArgAction::Append), "Flags should precede `...`");
+        debug_assert_eq!($arg.get_value_names(), None, "Multiple values not yet supported");
 
-                let mut arg = $arg;
+        let mut arg = $arg;
 
-                if arg.get_long().is_none() && arg.get_short().is_none() {
-                    arg = arg.required(false);
-                } else {
-                    arg = arg.num_args(0..=1);
-                }
-
-                let value_name = $crate::arg_impl! { @string $value_name };
-                if arg.get_id() == "" {
-                    arg = arg.id(value_name);
-                }
-                arg
-                    .value_name(value_name)
-                    .action($crate::ArgAction::Set)
-            })
-            $($tail)*
+        if arg.get_long().is_none() && arg.get_short().is_none() {
+            arg = arg.required(false);
+        } else {
+            arg = arg.num_args(0..=1);
         }
-    };
+
+        let value_name = $crate::arg_impl! { @string $value_name };
+        if arg.get_id() == "" {
+            arg = arg.id(value_name);
+        }
+        let arg = arg
+            .value_name(value_name)
+            .action($crate::ArgAction::Set);
+        let arg = $crate::arg_impl! {
+            @arg (arg) $($tail)*
+        };
+        arg
+    }};
     (
         @arg
         ($arg:expr)
         [$value_name:literal]
         $($tail:tt)*
-    ) => {
-        $crate::arg_impl! {
-            @arg
-            ({
-                debug_assert!(!matches!($arg.get_action(), $crate::ArgAction::Append), "Flags should precede `...`");
-                debug_assert_eq!($arg.get_value_names(), None, "Multiple values not yet supported");
+    ) => {{
+        debug_assert!(!matches!($arg.get_action(), $crate::ArgAction::Append), "Flags should precede `...`");
+        debug_assert_eq!($arg.get_value_names(), None, "Multiple values not yet supported");
 
-                let mut arg = $arg;
+        let mut arg = $arg;
 
-                if arg.get_long().is_none() && arg.get_short().is_none() {
-                    arg = arg.required(false);
-                } else {
-                    arg = arg.num_args(0..=1);
-                }
-
-                let value_name = $crate::arg_impl! { @string $value_name };
-                if arg.get_id() == "" {
-                    arg = arg.id(value_name);
-                }
-                arg
-                    .value_name(value_name)
-                    .action($crate::ArgAction::Set)
-            })
-            $($tail)*
+        if arg.get_long().is_none() && arg.get_short().is_none() {
+            arg = arg.required(false);
+        } else {
+            arg = arg.num_args(0..=1);
         }
-    };
+
+        let value_name = $crate::arg_impl! { @string $value_name };
+        if arg.get_id() == "" {
+            arg = arg.id(value_name);
+        }
+        let arg = arg
+            .value_name(value_name)
+            .action($crate::ArgAction::Set);
+        let arg = $crate::arg_impl! {
+            @arg (arg) $($tail)*
+        };
+        arg
+    }};
     (
         @arg
         ($arg:expr)
         ...
         $($tail:tt)*
-    ) => {
-        $crate::arg_impl! {
-            @arg
-            ({
-                match $arg.get_action() {
-                    $crate::ArgAction::Set => {
-                        if $arg.get_long().is_none() && $arg.get_short().is_none() {
-                            $arg.num_args(1..)
-                                // Allow collecting arguments interleaved with flags
-                                .action($crate::ArgAction::Append)
-                        } else {
-                            $arg.action($crate::ArgAction::Append)
-                        }
-                    },
-                    $crate::ArgAction::SetTrue | $crate::ArgAction::Help | $crate::ArgAction::Version => {
-                        $arg.action($crate::ArgAction::Count)
-                    }
-                    action => {
-                        panic!("Unexpected action {:?}", action)
-                    }
+    ) => {{
+        let arg = match $arg.get_action() {
+            $crate::ArgAction::Set => {
+                if $arg.get_long().is_none() && $arg.get_short().is_none() {
+                    $arg.num_args(1..)
+                        // Allow collecting arguments interleaved with flags
+                        .action($crate::ArgAction::Append)
+                } else {
+                    $arg.action($crate::ArgAction::Append)
                 }
-            })
-            $($tail)*
-        }
-    };
+            },
+            $crate::ArgAction::SetTrue | $crate::ArgAction::Help | $crate::ArgAction::Version => {
+                $arg.action($crate::ArgAction::Count)
+            }
+            action => {
+                panic!("Unexpected action {:?}", action)
+            }
+        };
+        let arg = $crate::arg_impl! {
+            @arg (arg) $($tail)*
+        };
+        arg
+    }};
     (
         @arg
         ($arg:expr)
         $help:literal
-    ) => {
+    ) => {{
         $arg.help($help)
-    };
+    }};
     (
         @arg
         ($arg:expr)
-    ) => {
+    ) => {{
         $arg
-    };
+    }};
 }
 
 /// Create an [`Arg`] from a usage string.
@@ -536,14 +524,17 @@
 /// [`Arg`]: crate::Arg
 #[macro_export]
 macro_rules! arg {
-    ( $name:ident: $($tail:tt)+ ) => {
-        $crate::arg_impl! {
-            @arg ($crate::Arg::new($crate::arg_impl! { @string $name })) $($tail)+
-        }
-    };
-    ( $($tail:tt)+ ) => {{
+    ( $name:ident: $($tail:tt)+ ) => {{
+        let arg = $crate::Arg::new($crate::arg_impl! { @string $name });
         let arg = $crate::arg_impl! {
-            @arg ($crate::Arg::default()) $($tail)+
+            @arg (arg) $($tail)+
+        };
+        arg
+    }};
+    ( $($tail:tt)+ ) => {{
+        let arg = $crate::Arg::default();
+        let arg = $crate::arg_impl! {
+            @arg (arg) $($tail)+
         };
         debug_assert_ne!(arg.get_id(), "", "Without a value or long flag, the `name:` prefix is required");
         arg
diff --git a/src/output/help_template.rs b/src/output/help_template.rs
index 3db80da..4c7adda 100644
--- a/src/output/help_template.rs
+++ b/src/output/help_template.rs
@@ -137,6 +137,7 @@
                     "name" => {
                         self.write_display_name();
                     }
+                    #[cfg(not(feature = "unstable-v5"))]
                     "bin" => {
                         self.write_bin_name();
                     }
@@ -409,7 +410,7 @@
                         self.none("\n\n");
                     }
                     first = false;
-                    self.header(format!("{}:\n", heading));
+                    self.header(format!("{heading}:\n"));
                     self.write_args(&args, heading, option_sort_key);
                 }
             }
@@ -484,7 +485,7 @@
         debug!("HelpTemplate::short");
 
         if let Some(s) = arg.get_short() {
-            self.literal(format!("-{}", s));
+            self.literal(format!("-{s}"));
         } else if arg.get_long().is_some() {
             self.none("    ");
         }
@@ -497,7 +498,7 @@
             if arg.get_short().is_some() {
                 self.none(", ");
             }
-            self.literal(format!("--{}", long));
+            self.literal(format!("--{long}"));
         }
     }
 
@@ -737,7 +738,7 @@
                 .map(|pvs| pvs.to_string_lossy())
                 .map(|pvs| {
                     if pvs.contains(char::is_whitespace) {
-                        Cow::from(format!("{:?}", pvs))
+                        Cow::from(format!("{pvs:?}"))
                     } else {
                         pvs
                     }
@@ -745,7 +746,7 @@
                 .collect::<Vec<_>>()
                 .join(" ");
 
-            spec_vals.push(format!("[default: {}]", pvs));
+            spec_vals.push(format!("[default: {pvs}]"));
         }
 
         let als = a
@@ -757,7 +758,7 @@
             .join(", ");
         if !als.is_empty() {
             debug!("HelpTemplate::spec_vals: Found aliases...{:?}", a.aliases);
-            spec_vals.push(format!("[aliases: {}]", als));
+            spec_vals.push(format!("[aliases: {als}]"));
         }
 
         let als = a
@@ -772,7 +773,7 @@
                 "HelpTemplate::spec_vals: Found short aliases...{:?}",
                 a.short_aliases
             );
-            spec_vals.push(format!("[short aliases: {}]", als));
+            spec_vals.push(format!("[short aliases: {als}]"));
         }
 
         let possible_vals = a.get_possible_values();
@@ -791,7 +792,7 @@
                 .collect::<Vec<_>>()
                 .join(", ");
 
-            spec_vals.push(format!("[possible values: {}]", pvs));
+            spec_vals.push(format!("[possible values: {pvs}]"));
         }
         let connector = if self.use_long { "\n" } else { " " };
         spec_vals.join(connector)
@@ -834,11 +835,11 @@
             styled.literal(subcommand.get_name());
             if let Some(short) = subcommand.get_short_flag() {
                 styled.none(", ");
-                styled.literal(format!("-{}", short));
+                styled.literal(format!("-{short}"));
             }
             if let Some(long) = subcommand.get_long_flag() {
                 styled.none(", ");
-                styled.literal(format!("--{}", long));
+                styled.literal(format!("--{long}"));
             }
             longest = longest.max(styled.display_width());
             ord_v.push((subcommand.get_display_order(), styled, subcommand));
@@ -901,7 +902,7 @@
 
         let mut short_als = a
             .get_visible_short_flag_aliases()
-            .map(|a| format!("-{}", a))
+            .map(|a| format!("-{a}"))
             .collect::<Vec<_>>();
         let als = a.get_visible_aliases().map(|s| s.to_string());
         short_als.extend(als);
@@ -915,7 +916,7 @@
                 "HelpTemplate::spec_vals: Found short flag aliases...{:?}",
                 a.get_all_short_flag_aliases().collect::<Vec<_>>()
             );
-            spec_vals.push(format!("[aliases: {}]", all_als));
+            spec_vals.push(format!("[aliases: {all_als}]"));
         }
 
         spec_vals.join(" ")
diff --git a/src/output/textwrap/core.rs b/src/output/textwrap/core.rs
index b890c6c..25c9eb6 100644
--- a/src/output/textwrap/core.rs
+++ b/src/output/textwrap/core.rs
@@ -105,7 +105,7 @@
                 assert_eq!(ch.width().unwrap(), 1, "char: {}", desc);
 
                 #[cfg(not(feature = "unicode"))]
-                assert_eq!(ch_width(ch), 1, "char: {}", desc);
+                assert_eq!(ch_width(ch), 1, "char: {desc}");
             }
         }
 
@@ -123,7 +123,7 @@
                 assert!(ch.width().unwrap() <= 2, "char: {}", desc);
 
                 #[cfg(not(feature = "unicode"))]
-                assert_eq!(ch_width(ch), 1, "char: {}", desc);
+                assert_eq!(ch_width(ch), 1, "char: {desc}");
             }
         }
 
diff --git a/src/parser/arg_matcher.rs b/src/parser/arg_matcher.rs
index 93bac7e..d584689 100644
--- a/src/parser/arg_matcher.rs
+++ b/src/parser/arg_matcher.rs
@@ -113,6 +113,10 @@
         self.matches.args.keys()
     }
 
+    pub(crate) fn args(&self) -> crate::util::flat_map::Iter<'_, Id, MatchedArg> {
+        self.matches.args.iter()
+    }
+
     pub(crate) fn entry(&mut self, arg: Id) -> crate::util::Entry<Id, MatchedArg> {
         self.matches.args.entry(arg)
     }
@@ -182,7 +186,7 @@
         let num_pending = self
             .pending
             .as_ref()
-            .and_then(|p| (p.id == *o.get_id()).then(|| p.raw_vals.len()))
+            .and_then(|p| (p.id == *o.get_id()).then_some(p.raw_vals.len()))
             .unwrap_or(0);
         debug!(
             "ArgMatcher::needs_more_vals: o={}, pending={}",
@@ -213,9 +217,9 @@
             raw_vals: Default::default(),
             trailing_idx: None,
         });
-        debug_assert_eq!(pending.id, *id, "{}", INTERNAL_ERROR_MSG);
+        debug_assert_eq!(pending.id, *id, "{INTERNAL_ERROR_MSG}");
         if ident.is_some() {
-            debug_assert_eq!(pending.ident, ident, "{}", INTERNAL_ERROR_MSG);
+            debug_assert_eq!(pending.ident, ident, "{INTERNAL_ERROR_MSG}");
         }
         if trailing_values {
             pending.trailing_idx.get_or_insert(pending.raw_vals.len());
diff --git a/src/parser/error.rs b/src/parser/error.rs
index 5652336..66b2bc7 100644
--- a/src/parser/error.rs
+++ b/src/parser/error.rs
@@ -27,10 +27,7 @@
             }
             Err(err) => err,
         };
-        panic!(
-            "Mismatch between definition and access of `{}`. {}",
-            id, err
-        )
+        panic!("Mismatch between definition and access of `{id}`. {err}",)
     }
 }
 
@@ -42,8 +39,7 @@
             Self::Downcast { actual, expected } => {
                 writeln!(
                     f,
-                    "Could not downcast to {:?}, need to downcast to {:?}",
-                    expected, actual
+                    "Could not downcast to {expected:?}, need to downcast to {actual:?}"
                 )
             }
             Self::UnknownArgument {} => {
diff --git a/src/parser/features/suggestions.rs b/src/parser/features/suggestions.rs
index f0aa502..b8bb7ad 100644
--- a/src/parser/features/suggestions.rs
+++ b/src/parser/features/suggestions.rs
@@ -4,10 +4,9 @@
 // Internal
 use crate::builder::Command;
 
-/// Produces multiple strings from a given list of possible values which are similar
-/// to the passed in value `v` within a certain confidence by least confidence.
-/// Thus in a list of possible values like ["foo", "bar"], the value "fop" will yield
-/// `Some("foo")`, whereas "blark" would yield `None`.
+/// Find strings from an iterable of `possible_values` similar to a given value `v`
+/// Returns a Vec of all possible values that exceed a similarity threshold
+/// sorted by ascending similarity, most similar comes last
 #[cfg(feature = "suggestions")]
 pub(crate) fn did_you_mean<T, I>(v: &str, possible_values: I) -> Vec<String>
 where
@@ -16,8 +15,11 @@
 {
     let mut candidates: Vec<(f64, String)> = possible_values
         .into_iter()
-        .map(|pv| (strsim::jaro_winkler(v, pv.as_ref()), pv.as_ref().to_owned()))
-        .filter(|(confidence, _)| *confidence > 0.8)
+        // GH #4660: using `jaro` because `jaro_winkler` implementation in `strsim-rs` is wrong
+        // causing strings with common prefix >=10 to be considered perfectly similar
+        .map(|pv| (strsim::jaro(v, pv.as_ref()), pv.as_ref().to_owned()))
+        // Confidence of 0.7 so that bar -> baz is suggested
+        .filter(|(confidence, _)| *confidence > 0.7)
         .collect();
     candidates.sort_by(|a, b| a.0.partial_cmp(&b.0).unwrap_or(Ordering::Equal));
     candidates.into_iter().map(|(_, pv)| pv).collect()
@@ -72,34 +74,94 @@
     }
 }
 
-#[cfg(all(test, features = "suggestions"))]
+#[cfg(all(test, feature = "suggestions"))]
 mod test {
     use super::*;
 
     #[test]
-    fn possible_values_match() {
+    fn missing_letter() {
         let p_vals = ["test", "possible", "values"];
-        assert_eq!(did_you_mean("tst", p_vals.iter()), Some("test"));
+        assert_eq!(did_you_mean("tst", p_vals.iter()), vec!["test"]);
     }
 
     #[test]
-    fn possible_values_match() {
-        let p_vals = ["test", "temp"];
-        assert_eq!(did_you_mean("te", p_vals.iter()), Some("test"));
+    fn ambiguous() {
+        let p_vals = ["test", "temp", "possible", "values"];
+        assert_eq!(did_you_mean("te", p_vals.iter()), vec!["test", "temp"]);
     }
 
     #[test]
-    fn possible_values_nomatch() {
-        let p_vals = ["test", "possible", "values"];
-        assert!(did_you_mean("hahaahahah", p_vals.iter()).is_none());
-    }
-
-    #[test]
-    fn flag() {
+    fn unrelated() {
         let p_vals = ["test", "possible", "values"];
         assert_eq!(
-            did_you_mean_flag("tst", p_vals.iter(), []),
-            Some(("test", None))
+            did_you_mean("hahaahahah", p_vals.iter()),
+            Vec::<String>::new()
+        );
+    }
+
+    #[test]
+    fn best_fit() {
+        let p_vals = [
+            "test",
+            "possible",
+            "values",
+            "alignmentStart",
+            "alignmentScore",
+        ];
+        assert_eq!(
+            did_you_mean("alignmentScorr", p_vals.iter()),
+            vec!["alignmentStart", "alignmentScore"]
+        );
+    }
+
+    #[test]
+    fn best_fit_long_common_prefix_issue_4660() {
+        let p_vals = ["alignmentScore", "alignmentStart"];
+        assert_eq!(
+            did_you_mean("alignmentScorr", p_vals.iter()),
+            vec!["alignmentStart", "alignmentScore"]
+        );
+    }
+
+    #[test]
+    fn flag_missing_letter() {
+        let p_vals = ["test", "possible", "values"];
+        assert_eq!(
+            did_you_mean_flag("tst", &[], p_vals.iter(), []),
+            Some(("test".to_owned(), None))
+        );
+    }
+
+    #[test]
+    fn flag_ambiguous() {
+        let p_vals = ["test", "temp", "possible", "values"];
+        assert_eq!(
+            did_you_mean_flag("te", &[], p_vals.iter(), []),
+            Some(("temp".to_owned(), None))
+        );
+    }
+
+    #[test]
+    fn flag_unrelated() {
+        let p_vals = ["test", "possible", "values"];
+        assert_eq!(
+            did_you_mean_flag("hahaahahah", &[], p_vals.iter(), []),
+            None
+        );
+    }
+
+    #[test]
+    fn flag_best_fit() {
+        let p_vals = [
+            "test",
+            "possible",
+            "values",
+            "alignmentStart",
+            "alignmentScore",
+        ];
+        assert_eq!(
+            did_you_mean_flag("alignmentScorr", &[], p_vals.iter(), []),
+            Some(("alignmentScore".to_owned(), None))
         );
     }
 }
diff --git a/src/parser/matches/arg_matches.rs b/src/parser/matches/arg_matches.rs
index 36d2ca9..13ceea3 100644
--- a/src/parser/matches/arg_matches.rs
+++ b/src/parser/matches/arg_matches.rs
@@ -216,6 +216,43 @@
         MatchesError::unwrap(id, self.try_get_many(id))
     }
 
+    /// Iterate over the values passed to each occurrence of an option.
+    ///
+    /// Each item is itself an iterator containing the arguments passed to a single occurrence
+    /// of the option.
+    ///
+    /// If the option doesn't support multiple occurrences, or there was only a single occurrence,
+    /// the iterator will only contain a single item.
+    ///
+    /// Returns `None` if the option wasn't present.
+    ///
+    /// # Panics
+    ///
+    /// If the argument definition and access mismatch. To handle this case programmatically, see
+    /// [`ArgMatches::try_get_occurrences`].
+    ///
+    /// # Examples
+    /// ```rust
+    /// # use clap::{Command,Arg, ArgAction, value_parser};
+    /// let m = Command::new("myprog")
+    ///     .arg(Arg::new("x")
+    ///         .short('x')
+    ///         .num_args(2)
+    ///         .action(ArgAction::Append)
+    ///         .value_parser(value_parser!(String)))
+    ///     .get_matches_from(vec![
+    ///         "myprog", "-x", "a", "b", "-x", "c", "d"]);
+    /// let vals: Vec<Vec<&String>> = m.get_occurrences("x").unwrap().map(Iterator::collect).collect();
+    /// assert_eq!(vals, [["a", "b"], ["c", "d"]]);
+    /// ```
+    #[cfg_attr(debug_assertions, track_caller)]
+    pub fn get_occurrences<T: Any + Clone + Send + Sync + 'static>(
+        &self,
+        id: &str,
+    ) -> Option<OccurrencesRef<T>> {
+        MatchesError::unwrap(id, self.try_get_occurrences(id))
+    }
+
     /// Iterate over the original argument values.
     ///
     /// An `OsStr` on Unix-like systems is any series of bytes, regardless of whether or not they
@@ -262,6 +299,59 @@
         MatchesError::unwrap(id, self.try_get_raw(id))
     }
 
+    /// Iterate over the original values for each occurrence of an option.
+    ///
+    /// Similar to [`ArgMatches::get_occurrences`] but returns raw values.
+    ///
+    /// An `OsStr` on Unix-like systems is any series of bytes, regardless of whether or not they
+    /// contain valid UTF-8. Since [`String`]s in Rust are guaranteed to be valid UTF-8, a valid
+    /// filename on a Unix system as an argument value may contain invalid UTF-8.
+    ///
+    /// Returns `None` if the option wasn't present.
+    ///
+    /// # Panic
+    ///
+    /// If the argument definition and access mismatch.  To handle this case programmatically, see
+    /// [`ArgMatches::try_get_raw_occurrences`].
+    ///
+    /// # Examples
+    ///
+    #[cfg_attr(not(unix), doc = " ```ignore")]
+    #[cfg_attr(unix, doc = " ```")]
+    /// # use clap::{Command, arg, value_parser, ArgAction, Arg};
+    /// # use std::ffi::{OsStr,OsString};
+    /// # use std::os::unix::ffi::{OsStrExt,OsStringExt};
+    /// use std::path::PathBuf;
+    ///
+    /// let m = Command::new("myprog")
+    ///     .arg(Arg::new("x")
+    ///         .short('x')
+    ///         .num_args(2)
+    ///         .action(ArgAction::Append)
+    ///         .value_parser(value_parser!(PathBuf)))
+    ///     .get_matches_from(vec![OsString::from("myprog"),
+    ///                             OsString::from("-x"),
+    ///                             OsString::from("a"), OsString::from("b"),
+    ///                             OsString::from("-x"),
+    ///                             OsString::from("c"),
+    ///                             // "{0xe9}!"
+    ///                             OsString::from_vec(vec![0xe9, b'!'])]);
+    /// let mut itr = m.get_raw_occurrences("x")
+    ///     .expect("`-x`is required")
+    ///     .map(Iterator::collect::<Vec<_>>);
+    /// assert_eq!(itr.next(), Some(vec![OsStr::new("a"), OsStr::new("b")]));
+    /// assert_eq!(itr.next(), Some(vec![OsStr::new("c"), OsStr::from_bytes(&[0xe9, b'!'])]));
+    /// assert_eq!(itr.next(), None);
+    /// ```
+    /// [`Iterator`]: std::iter::Iterator
+    /// [`OsStr`]: std::ffi::OsStr
+    /// [values]: OsValues
+    /// [`String`]: std::string::String
+    #[cfg_attr(debug_assertions, track_caller)]
+    pub fn get_raw_occurrences(&self, id: &str) -> Option<RawOccurrences<'_>> {
+        MatchesError::unwrap(id, self.try_get_raw_occurrences(id))
+    }
+
     /// Returns the value of a specific option or positional argument.
     ///
     /// i.e. an argument that [takes an additional value][crate::Arg::num_args] at runtime.
@@ -338,6 +428,44 @@
         MatchesError::unwrap(id, self.try_remove_many(id))
     }
 
+    /// Return values for each occurrence of an option.
+    ///
+    /// Each item is itself an iterator containing the arguments passed to a single occurrence of
+    /// the option.
+    ///
+    /// If the option doesn't support multiple occurrences, or there was only a single occurrence,
+    /// the iterator will only contain a single item.
+    ///
+    /// Returns `None` if the option wasn't present.
+    ///
+    /// # Panic
+    ///
+    /// If the argument definition and access mismatch.  To handle this case programmatically, see
+    /// [`ArgMatches::try_remove_occurrences`].
+    ///
+    /// # Examples
+    ///
+    /// ```rust
+    /// # use clap::{Command, Arg, value_parser, ArgAction};
+    /// let mut m = Command::new("myprog")
+    ///     .arg(Arg::new("x")
+    ///         .short('x')
+    ///         .num_args(2)
+    ///         .action(ArgAction::Append)
+    ///         .value_parser(value_parser!(String)))
+    ///     .get_matches_from(vec![
+    ///         "myprog", "-x", "a", "b", "-x", "c", "d"]);
+    /// let vals: Vec<Vec<String>> = m.remove_occurrences("x").unwrap().map(Iterator::collect).collect();
+    /// assert_eq!(vals, [["a", "b"], ["c", "d"]]);
+    /// ```
+    #[cfg_attr(debug_assertions, track_caller)]
+    pub fn remove_occurrences<T: Any + Clone + Send + Sync + 'static>(
+        &mut self,
+        id: &str,
+    ) -> Option<Occurrences<T>> {
+        MatchesError::unwrap(id, self.try_remove_occurrences(id))
+    }
+
     /// Check if values are present for the argument or group id
     ///
     /// *NOTE:* This will always return `true` if [`default_value`] has been set.
@@ -345,7 +473,7 @@
     ///
     /// # Panics
     ///
-    /// If `id` is is not a valid argument or group name.  To handle this case programmatically, see
+    /// If `id` is not a valid argument or group name.  To handle this case programmatically, see
     /// [`ArgMatches::try_contains_id`].
     ///
     /// # Examples
@@ -453,6 +581,11 @@
     /// [`Iterator`]: std::iter::Iterator
     #[cfg(feature = "unstable-grouped")]
     #[cfg_attr(debug_assertions, track_caller)]
+    #[deprecated(
+        since = "4.1.0",
+        note = "Use get_occurrences or remove_occurrences instead"
+    )]
+    #[allow(deprecated)]
     pub fn grouped_values_of(&self, id: &str) -> Option<GroupedValues> {
         let arg = some!(self.get_arg(id));
         let v = GroupedValues {
@@ -466,7 +599,7 @@
     ///
     /// # Panics
     ///
-    /// If `id` is is not a valid argument or group id.
+    /// If `id` is not a valid argument or group id.
     ///
     /// # Examples
     ///
@@ -512,7 +645,7 @@
     ///
     /// # Panics
     ///
-    /// If `id` is is not a valid argument or group id.
+    /// If `id` is not a valid argument or group id.
     ///
     /// # Examples
     ///
@@ -655,7 +788,7 @@
     ///
     /// # Panics
     ///
-    /// If `id` is is not a valid argument or group id.
+    /// If `id` is not a valid argument or group id.
     ///
     /// # Examples
     ///
@@ -852,7 +985,7 @@
     ///
     /// # Panics
     ///
-    /// If `id` is is not a valid subcommand.
+    /// If `id` is not a valid subcommand.
     ///
     /// # Examples
     ///
@@ -872,7 +1005,7 @@
     ///     ]);
     ///
     /// // Both parent commands, and child subcommands can have arguments present at the same times
-    /// assert!(*app_m.get_one::<bool>("debug").expect("defaulted by clap"));
+    /// assert!(app_m.get_flag("debug"));
     ///
     /// // Get the subcommand's ArgMatches instance
     /// if let Some(sub_m) = app_m.subcommand_matches("test") {
@@ -967,12 +1100,29 @@
         let values = arg.vals_flatten();
         let values = ValuesRef {
             // enforced by `try_get_arg_t`
-            iter: values.map(|v| v.downcast_ref::<T>().expect(INTERNAL_ERROR_MSG)),
+            iter: values.map(unwrap_downcast_ref),
             len,
         };
         Ok(Some(values))
     }
 
+    /// Non-panicking version of [`ArgMatches::get_occurrences`]
+    pub fn try_get_occurrences<T: Any + Clone + Send + Sync + 'static>(
+        &self,
+        id: &str,
+    ) -> Result<Option<OccurrencesRef<T>>, MatchesError> {
+        let arg = match ok!(self.try_get_arg_t::<T>(id)) {
+            Some(arg) => arg,
+            None => return Ok(None),
+        };
+        let values = arg.vals();
+        Ok(Some(OccurrencesRef {
+            iter: values.map(|g| OccurrenceValuesRef {
+                iter: g.iter().map(unwrap_downcast_ref),
+            }),
+        }))
+    }
+
     /// Non-panicking version of [`ArgMatches::get_raw`]
     pub fn try_get_raw(&self, id: &str) -> Result<Option<RawValues<'_>>, MatchesError> {
         let arg = match ok!(self.try_get_arg(id)) {
@@ -988,6 +1138,24 @@
         Ok(Some(values))
     }
 
+    /// Non-panicking version of [`ArgMatches::get_raw_occurrences`]
+    pub fn try_get_raw_occurrences(
+        &self,
+        id: &str,
+    ) -> Result<Option<RawOccurrences<'_>>, MatchesError> {
+        let arg = match ok!(self.try_get_arg(id)) {
+            Some(arg) => arg,
+            None => return Ok(None),
+        };
+        let values = arg.raw_vals();
+        let occurrences = RawOccurrences {
+            iter: values.map(|g| RawOccurrenceValues {
+                iter: g.iter().map(OsString::as_os_str),
+            }),
+        };
+        Ok(Some(occurrences))
+    }
+
     /// Non-panicking version of [`ArgMatches::remove_one`]
     pub fn try_remove_one<T: Any + Clone + Send + Sync + 'static>(
         &mut self,
@@ -997,7 +1165,7 @@
             Some(values) => Ok(values
                 .into_vals_flatten()
                 // enforced by `try_get_arg_t`
-                .map(|v| v.downcast_into::<T>().expect(INTERNAL_ERROR_MSG))
+                .map(unwrap_downcast_into)
                 .next()),
             None => Ok(None),
         }
@@ -1016,12 +1184,30 @@
         let values = arg.into_vals_flatten();
         let values = Values {
             // enforced by `try_get_arg_t`
-            iter: values.map(|v| v.downcast_into::<T>().expect(INTERNAL_ERROR_MSG)),
+            iter: values.map(unwrap_downcast_into),
             len,
         };
         Ok(Some(values))
     }
 
+    /// Non-panicking version of [`ArgMatches::remove_occurrences`]
+    pub fn try_remove_occurrences<T: Any + Clone + Send + Sync + 'static>(
+        &mut self,
+        id: &str,
+    ) -> Result<Option<Occurrences<T>>, MatchesError> {
+        let arg = match ok!(self.try_remove_arg_t::<T>(id)) {
+            Some(arg) => arg,
+            None => return Ok(None),
+        };
+        let values = arg.into_vals();
+        let occurrences = Occurrences {
+            iter: values.into_iter().map(|g| OccurrenceValues {
+                iter: g.into_iter().map(unwrap_downcast_into),
+            }),
+        };
+        Ok(Some(occurrences))
+    }
+
     /// Non-panicking version of [`ArgMatches::contains_id`]
     pub fn try_contains_id(&self, id: &str) -> Result<bool, MatchesError> {
         ok!(self.verify_arg(id));
@@ -1116,10 +1302,9 @@
             if arg == Id::EXTERNAL || self.valid_args.iter().any(|s| *s == arg) {
             } else {
                 panic!(
-                    "`{:?}` is not an id of an argument or a group.\n\
+                    "`{arg:?}` is not an id of an argument or a group.\n\
                      Make sure you're using the name of the argument itself \
-                     and not the name of short or long flags.",
-                    arg
+                     and not the name of short or long flags."
                 );
             }
         }
@@ -1134,7 +1319,7 @@
         {
             if name.is_empty() || self.valid_subcommands.iter().any(|s| *s == name) {
             } else {
-                panic!("`{}` is not a name of a subcommand.", name);
+                panic!("`{name}` is not a name of a subcommand.");
             }
         }
 
@@ -1377,14 +1562,15 @@
 // commit: be5e1fa3c26e351761b33010ddbdaf5f05dbcc33
 // license: MIT - Copyright (c) 2015 The Rust Project Developers
 
-#[derive(Clone)]
-#[allow(missing_debug_implementations)]
+#[derive(Clone, Debug)]
+#[deprecated(since = "4.1.0", note = "Use Occurrences instead")]
 pub struct GroupedValues<'a> {
     #[allow(clippy::type_complexity)]
     iter: Map<Iter<'a, Vec<AnyValue>>, fn(&Vec<AnyValue>) -> Vec<&str>>,
     len: usize,
 }
 
+#[allow(deprecated)]
 impl<'a> Iterator for GroupedValues<'a> {
     type Item = Vec<&'a str>;
 
@@ -1396,15 +1582,18 @@
     }
 }
 
+#[allow(deprecated)]
 impl<'a> DoubleEndedIterator for GroupedValues<'a> {
     fn next_back(&mut self) -> Option<Self::Item> {
         self.iter.next_back()
     }
 }
 
+#[allow(deprecated)]
 impl<'a> ExactSizeIterator for GroupedValues<'a> {}
 
 /// Creates an empty iterator. Used for `unwrap_or_default()`.
+#[allow(deprecated)]
 impl<'a> Default for GroupedValues<'a> {
     fn default() -> Self {
         static EMPTY: [Vec<AnyValue>; 0] = [];
@@ -1415,6 +1604,206 @@
     }
 }
 
+#[derive(Clone, Debug)]
+pub struct Occurrences<T> {
+    #[allow(clippy::type_complexity)]
+    iter: Map<std::vec::IntoIter<Vec<AnyValue>>, fn(Vec<AnyValue>) -> OccurrenceValues<T>>,
+}
+
+impl<T> Iterator for Occurrences<T> {
+    type Item = OccurrenceValues<T>;
+
+    fn next(&mut self) -> Option<Self::Item> {
+        self.iter.next()
+    }
+
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        self.iter.size_hint()
+    }
+}
+
+impl<T> DoubleEndedIterator for Occurrences<T> {
+    fn next_back(&mut self) -> Option<Self::Item> {
+        self.iter.next_back()
+    }
+}
+
+impl<T> ExactSizeIterator for Occurrences<T> {}
+
+impl<T> Default for Occurrences<T> {
+    fn default() -> Self {
+        let empty: Vec<Vec<AnyValue>> = Default::default();
+        Occurrences {
+            iter: empty.into_iter().map(|_| unreachable!()),
+        }
+    }
+}
+
+#[derive(Clone, Debug)]
+pub struct OccurrenceValues<T> {
+    #[allow(clippy::type_complexity)]
+    iter: Map<std::vec::IntoIter<AnyValue>, fn(AnyValue) -> T>,
+}
+
+impl<T> Iterator for OccurrenceValues<T> {
+    type Item = T;
+
+    fn next(&mut self) -> Option<Self::Item> {
+        self.iter.next()
+    }
+
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        self.iter.size_hint()
+    }
+}
+
+impl<T> DoubleEndedIterator for OccurrenceValues<T> {
+    fn next_back(&mut self) -> Option<Self::Item> {
+        self.iter.next_back()
+    }
+}
+
+impl<T> ExactSizeIterator for OccurrenceValues<T> {}
+
+#[derive(Clone, Debug)]
+pub struct OccurrencesRef<'a, T> {
+    #[allow(clippy::type_complexity)]
+    iter: Map<Iter<'a, Vec<AnyValue>>, fn(&Vec<AnyValue>) -> OccurrenceValuesRef<'_, T>>,
+}
+
+impl<'a, T> Iterator for OccurrencesRef<'a, T>
+where
+    Self: 'a,
+{
+    type Item = OccurrenceValuesRef<'a, T>;
+
+    fn next(&mut self) -> Option<Self::Item> {
+        self.iter.next()
+    }
+
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        self.iter.size_hint()
+    }
+}
+
+impl<'a, T> DoubleEndedIterator for OccurrencesRef<'a, T>
+where
+    Self: 'a,
+{
+    fn next_back(&mut self) -> Option<Self::Item> {
+        self.iter.next_back()
+    }
+}
+
+impl<'a, T> ExactSizeIterator for OccurrencesRef<'a, T> where Self: 'a {}
+impl<'a, T> Default for OccurrencesRef<'a, T> {
+    fn default() -> Self {
+        static EMPTY: [Vec<AnyValue>; 0] = [];
+        OccurrencesRef {
+            iter: EMPTY[..].iter().map(|_| unreachable!()),
+        }
+    }
+}
+
+#[derive(Clone, Debug)]
+pub struct OccurrenceValuesRef<'a, T> {
+    #[allow(clippy::type_complexity)]
+    iter: Map<Iter<'a, AnyValue>, fn(&AnyValue) -> &T>,
+}
+
+impl<'a, T> Iterator for OccurrenceValuesRef<'a, T>
+where
+    Self: 'a,
+{
+    type Item = &'a T;
+
+    fn next(&mut self) -> Option<Self::Item> {
+        self.iter.next()
+    }
+
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        self.iter.size_hint()
+    }
+}
+
+impl<'a, T> DoubleEndedIterator for OccurrenceValuesRef<'a, T>
+where
+    Self: 'a,
+{
+    fn next_back(&mut self) -> Option<Self::Item> {
+        self.iter.next_back()
+    }
+}
+
+impl<'a, T> ExactSizeIterator for OccurrenceValuesRef<'a, T> where Self: 'a {}
+
+#[derive(Clone, Debug)]
+pub struct RawOccurrences<'a> {
+    #[allow(clippy::type_complexity)]
+    iter: Map<Iter<'a, Vec<OsString>>, fn(&Vec<OsString>) -> RawOccurrenceValues<'_>>,
+}
+
+impl<'a> Iterator for RawOccurrences<'a> {
+    type Item = RawOccurrenceValues<'a>;
+
+    fn next(&mut self) -> Option<Self::Item> {
+        self.iter.next()
+    }
+
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        self.iter.size_hint()
+    }
+}
+
+impl<'a> DoubleEndedIterator for RawOccurrences<'a> {
+    fn next_back(&mut self) -> Option<Self::Item> {
+        self.iter.next_back()
+    }
+}
+
+impl<'a> ExactSizeIterator for RawOccurrences<'a> {}
+
+impl<'a> Default for RawOccurrences<'a> {
+    fn default() -> Self {
+        static EMPTY: [Vec<OsString>; 0] = [];
+        RawOccurrences {
+            iter: EMPTY[..].iter().map(|_| unreachable!()),
+        }
+    }
+}
+
+#[derive(Clone, Debug)]
+pub struct RawOccurrenceValues<'a> {
+    #[allow(clippy::type_complexity)]
+    iter: Map<Iter<'a, OsString>, fn(&OsString) -> &OsStr>,
+}
+
+impl<'a> Iterator for RawOccurrenceValues<'a>
+where
+    Self: 'a,
+{
+    type Item = &'a OsStr;
+
+    fn next(&mut self) -> Option<Self::Item> {
+        self.iter.next()
+    }
+
+    fn size_hint(&self) -> (usize, Option<usize>) {
+        self.iter.size_hint()
+    }
+}
+
+impl<'a> DoubleEndedIterator for RawOccurrenceValues<'a>
+where
+    Self: 'a,
+{
+    fn next_back(&mut self) -> Option<Self::Item> {
+        self.iter.next_back()
+    }
+}
+
+impl<'a> ExactSizeIterator for RawOccurrenceValues<'a> {}
+
 /// Iterate over indices for where an argument appeared when parsing, via [`ArgMatches::indices_of`]
 ///
 /// # Examples
@@ -1472,9 +1861,9 @@
     }
 }
 
-#[cfg(feature = "unstable-grouped")]
 #[cfg_attr(debug_assertions, track_caller)]
 #[inline]
+#[cfg(feature = "unstable-grouped")]
 fn unwrap_string(value: &AnyValue) -> &str {
     match value.downcast_ref::<String>() {
         Some(value) => value,
@@ -1484,6 +1873,16 @@
     }
 }
 
+#[track_caller]
+fn unwrap_downcast_ref<T: Any + Clone + Send + Sync + 'static>(value: &AnyValue) -> &T {
+    value.downcast_ref().expect(INTERNAL_ERROR_MSG)
+}
+
+#[track_caller]
+fn unwrap_downcast_into<T: Any + Clone + Send + Sync + 'static>(value: AnyValue) -> T {
+    value.downcast_into().expect(INTERNAL_ERROR_MSG)
+}
+
 #[cfg(test)]
 mod tests {
     use super::*;
diff --git a/src/parser/matches/matched_arg.rs b/src/parser/matches/matched_arg.rs
index 6a80625..901990c 100644
--- a/src/parser/matches/matched_arg.rs
+++ b/src/parser/matches/matched_arg.rs
@@ -75,11 +75,14 @@
         self.indices.push(index)
     }
 
-    #[cfg(feature = "unstable-grouped")]
     pub(crate) fn vals(&self) -> Iter<Vec<AnyValue>> {
         self.vals.iter()
     }
 
+    pub(crate) fn into_vals(self) -> Vec<Vec<AnyValue>> {
+        self.vals
+    }
+
     pub(crate) fn vals_flatten(&self) -> Flatten<Iter<Vec<AnyValue>>> {
         self.vals.iter().flatten()
     }
@@ -88,6 +91,10 @@
         self.vals.into_iter().flatten()
     }
 
+    pub(crate) fn raw_vals(&self) -> Iter<Vec<OsString>> {
+        self.raw_vals.iter()
+    }
+
     pub(crate) fn raw_vals_flatten(&self) -> Flatten<Iter<Vec<OsString>>> {
         self.raw_vals.iter().flatten()
     }
diff --git a/src/parser/parser.rs b/src/parser/parser.rs
index 9b7f9a9..2579034 100644
--- a/src/parser/parser.rs
+++ b/src/parser/parser.rs
@@ -502,33 +502,35 @@
             }
         }
 
-        let candidates = suggestions::did_you_mean(
-            &arg_os.display().to_string(),
-            self.cmd.all_subcommand_names(),
-        );
-        // If the argument looks like a subcommand.
-        if !candidates.is_empty() {
-            return ClapError::invalid_subcommand(
-                self.cmd,
-                arg_os.display().to_string(),
-                candidates,
-                self.cmd
-                    .get_bin_name()
-                    .unwrap_or_else(|| self.cmd.get_name())
-                    .to_owned(),
-                Usage::new(self.cmd).create_usage_with_title(&[]),
+        if !(self.cmd.is_args_conflicts_with_subcommands_set() && valid_arg_found) {
+            let candidates = suggestions::did_you_mean(
+                &arg_os.display().to_string(),
+                self.cmd.all_subcommand_names(),
             );
-        }
+            // If the argument looks like a subcommand.
+            if !candidates.is_empty() {
+                return ClapError::invalid_subcommand(
+                    self.cmd,
+                    arg_os.display().to_string(),
+                    candidates,
+                    self.cmd
+                        .get_bin_name()
+                        .unwrap_or_else(|| self.cmd.get_name())
+                        .to_owned(),
+                    Usage::new(self.cmd).create_usage_with_title(&[]),
+                );
+            }
 
-        // If the argument must be a subcommand.
-        if self.cmd.has_subcommands()
-            && (!self.cmd.has_positionals() || self.cmd.is_infer_subcommands_set())
-        {
-            return ClapError::unrecognized_subcommand(
-                self.cmd,
-                arg_os.display().to_string(),
-                Usage::new(self.cmd).create_usage_with_title(&[]),
-            );
+            // If the argument must be a subcommand.
+            if self.cmd.has_subcommands()
+                && (!self.cmd.has_positionals() || self.cmd.is_infer_subcommands_set())
+            {
+                return ClapError::unrecognized_subcommand(
+                    self.cmd,
+                    arg_os.display().to_string(),
+                    Usage::new(self.cmd).create_usage_with_title(&[]),
+                );
+            }
         }
 
         let suggested_trailing_arg = !trailing_values
@@ -893,8 +895,7 @@
         debug_assert_eq!(
             res,
             Ok(()),
-            "tracking of `flag_subcmd_skip` is off for `{:?}`",
-            short_arg
+            "tracking of `flag_subcmd_skip` is off for `{short_arg:?}`"
         );
         while let Some(c) = short_arg.next_flag() {
             let c = match c {
@@ -980,7 +981,7 @@
                 Ok(ParseResult::FlagSubCommand(name))
             } else {
                 Ok(ParseResult::NoMatchingArg {
-                    arg: format!("-{}", c),
+                    arg: format!("-{c}"),
                 })
             };
         }
@@ -1568,7 +1569,7 @@
             did_you_mean.is_none() && !trailing_values && self.cmd.has_positionals();
         ClapError::unknown_argument(
             self.cmd,
-            format!("--{}", arg),
+            format!("--{arg}"),
             did_you_mean,
             suggested_trailing_arg,
             Usage::new(self.cmd)
diff --git a/src/parser/validator.rs b/src/parser/validator.rs
index 0d97c2f..49d28a3 100644
--- a/src/parser/validator.rs
+++ b/src/parser/validator.rs
@@ -1,6 +1,6 @@
 // Internal
 use crate::builder::StyledStr;
-use crate::builder::{Arg, ArgPredicate, Command, PossibleValue};
+use crate::builder::{Arg, ArgGroup, ArgPredicate, Command, PossibleValue};
 use crate::error::{Error, Result as ClapResult};
 use crate::output::Usage;
 use crate::parser::{ArgMatcher, ParseState};
@@ -27,7 +27,7 @@
         matcher: &mut ArgMatcher,
     ) -> ClapResult<()> {
         debug!("Validator::validate");
-        let mut conflicts = Conflicts::new();
+        let conflicts = Conflicts::with_args(self.cmd, matcher);
         let has_subcmd = matcher.subcommand_name().is_some();
 
         if let ParseState::Opt(a) = parse_state {
@@ -54,8 +54,8 @@
 
         if !has_subcmd && self.cmd.is_arg_required_else_help_set() {
             let num_user_values = matcher
-                .arg_ids()
-                .filter(|arg_id| matcher.check_explicit(arg_id, &ArgPredicate::IsPresent))
+                .args()
+                .filter(|(_, matched)| matched.check_explicit(&ArgPredicate::IsPresent))
                 .count();
             if num_user_values == 0 {
                 let message = self.cmd.write_help_err(false);
@@ -80,9 +80,9 @@
             ));
         }
 
-        ok!(self.validate_conflicts(matcher, &mut conflicts));
+        ok!(self.validate_conflicts(matcher, &conflicts));
         if !(self.cmd.is_subcommand_negates_reqs_set() && has_subcmd) {
-            ok!(self.validate_required(matcher, &mut conflicts));
+            ok!(self.validate_required(matcher, &conflicts));
         }
 
         Ok(())
@@ -91,19 +91,19 @@
     fn validate_conflicts(
         &mut self,
         matcher: &ArgMatcher,
-        conflicts: &mut Conflicts,
+        conflicts: &Conflicts,
     ) -> ClapResult<()> {
         debug!("Validator::validate_conflicts");
 
         ok!(self.validate_exclusive(matcher));
 
-        for arg_id in matcher
-            .arg_ids()
-            .filter(|arg_id| matcher.check_explicit(arg_id, &ArgPredicate::IsPresent))
-            .filter(|arg_id| self.cmd.find(arg_id).is_some())
+        for (arg_id, _) in matcher
+            .args()
+            .filter(|(_, matched)| matched.check_explicit(&ArgPredicate::IsPresent))
+            .filter(|(arg_id, _)| self.cmd.find(arg_id).is_some())
         {
             debug!("Validator::validate_conflicts::iter: id={:?}", arg_id);
-            let conflicts = conflicts.gather_conflicts(self.cmd, matcher, arg_id);
+            let conflicts = conflicts.gather_conflicts(self.cmd, arg_id);
             ok!(self.build_conflict_err(arg_id, &conflicts, matcher));
         }
 
@@ -113,9 +113,9 @@
     fn validate_exclusive(&self, matcher: &ArgMatcher) -> ClapResult<()> {
         debug!("Validator::validate_exclusive");
         let args_count = matcher
-            .arg_ids()
-            .filter(|arg_id| {
-                matcher.check_explicit(arg_id, &crate::builder::ArgPredicate::IsPresent)
+            .args()
+            .filter(|(arg_id, matched)| {
+                matched.check_explicit(&crate::builder::ArgPredicate::IsPresent)
                     // Avoid including our own groups by checking none of them.  If a group is present, the
                     // args for the group will be.
                     && self.cmd.find(arg_id).is_some()
@@ -127,14 +127,12 @@
         }
 
         matcher
-            .arg_ids()
-            .filter(|arg_id| {
-                matcher.check_explicit(arg_id, &crate::builder::ArgPredicate::IsPresent)
-            })
-            .filter_map(|name| {
-                debug!("Validator::validate_exclusive:iter:{:?}", name);
+            .args()
+            .filter(|(_, matched)| matched.check_explicit(&crate::builder::ArgPredicate::IsPresent))
+            .filter_map(|(id, _)| {
+                debug!("Validator::validate_exclusive:iter:{:?}", id);
                 self.cmd
-                    .find(name)
+                    .find(id)
                     // Find `arg`s which are exclusive but also appear with other args.
                     .filter(|&arg| arg.is_exclusive_set() && args_count > 1)
             })
@@ -196,8 +194,9 @@
         conflicting_keys: &[Id],
     ) -> Option<StyledStr> {
         let used_filtered: Vec<Id> = matcher
-            .arg_ids()
-            .filter(|arg_id| matcher.check_explicit(arg_id, &ArgPredicate::IsPresent))
+            .args()
+            .filter(|(_, matched)| matched.check_explicit(&ArgPredicate::IsPresent))
+            .map(|(n, _)| n)
             .filter(|n| {
                 // Filter out the args we don't want to specify.
                 self.cmd.find(n).map_or(false, |a| !a.is_hide_set())
@@ -220,14 +219,14 @@
 
     fn gather_requires(&mut self, matcher: &ArgMatcher) {
         debug!("Validator::gather_requires");
-        for name in matcher
-            .arg_ids()
-            .filter(|arg_id| matcher.check_explicit(arg_id, &ArgPredicate::IsPresent))
+        for (name, matched) in matcher
+            .args()
+            .filter(|(_, matched)| matched.check_explicit(&ArgPredicate::IsPresent))
         {
             debug!("Validator::gather_requires:iter:{:?}", name);
             if let Some(arg) = self.cmd.find(name) {
                 let is_relevant = |(val, req_arg): &(ArgPredicate, Id)| -> Option<Id> {
-                    let required = matcher.check_explicit(arg.get_id(), val);
+                    let required = matched.check_explicit(val);
                     required.then(|| req_arg.clone())
                 };
 
@@ -243,11 +242,7 @@
         }
     }
 
-    fn validate_required(
-        &mut self,
-        matcher: &ArgMatcher,
-        conflicts: &mut Conflicts,
-    ) -> ClapResult<()> {
+    fn validate_required(&mut self, matcher: &ArgMatcher, conflicts: &Conflicts) -> ClapResult<()> {
         debug!("Validator::validate_required: required={:?}", self.required);
         self.gather_requires(matcher);
 
@@ -255,9 +250,9 @@
         let mut highest_index = 0;
 
         let is_exclusive_present = matcher
-            .arg_ids()
-            .filter(|arg_id| matcher.check_explicit(arg_id, &ArgPredicate::IsPresent))
-            .any(|id| {
+            .args()
+            .filter(|(_, matched)| matched.check_explicit(&ArgPredicate::IsPresent))
+            .any(|(id, _)| {
                 self.cmd
                     .find(id)
                     .map(|arg| arg.is_exclusive_set())
@@ -276,7 +271,7 @@
             debug!("Validator::validate_required:iter:aog={:?}", arg_or_group);
             if let Some(arg) = self.cmd.find(arg_or_group) {
                 debug!("Validator::validate_required:iter: This is an arg");
-                if !is_exclusive_present && !self.is_missing_required_ok(arg, matcher, conflicts) {
+                if !is_exclusive_present && !self.is_missing_required_ok(arg, conflicts) {
                     debug!(
                         "Validator::validate_required:iter: Missing {:?}",
                         arg.get_id()
@@ -374,15 +369,19 @@
         Ok(())
     }
 
-    fn is_missing_required_ok(
-        &self,
-        a: &Arg,
-        matcher: &ArgMatcher,
-        conflicts: &mut Conflicts,
-    ) -> bool {
+    fn is_missing_required_ok(&self, a: &Arg, conflicts: &Conflicts) -> bool {
         debug!("Validator::is_missing_required_ok: {}", a.get_id());
-        let conflicts = conflicts.gather_conflicts(self.cmd, matcher, a.get_id());
-        !conflicts.is_empty()
+        if !conflicts.gather_conflicts(self.cmd, a.get_id()).is_empty() {
+            debug!("Validator::is_missing_required_ok: true (self)");
+            return true;
+        }
+        for group_id in self.cmd.groups_for_arg(a.get_id()) {
+            if !conflicts.gather_conflicts(self.cmd, &group_id).is_empty() {
+                debug!("Validator::is_missing_required_ok: true ({})", group_id);
+                return true;
+            }
+        }
+        false
     }
 
     // Failing a required unless means, the arg's "unless" wasn't present, and neither were they
@@ -441,8 +440,9 @@
         );
 
         let used: Vec<Id> = matcher
-            .arg_ids()
-            .filter(|arg_id| matcher.check_explicit(arg_id, &ArgPredicate::IsPresent))
+            .args()
+            .filter(|(_, matched)| matched.check_explicit(&ArgPredicate::IsPresent))
+            .map(|(n, _)| n)
             .filter(|n| {
                 // Filter out the args we don't want to specify.
                 self.cmd.find(n).map_or(false, |a| !a.is_hide_set())
@@ -465,73 +465,91 @@
 }
 
 impl Conflicts {
-    fn new() -> Self {
-        Self::default()
+    fn with_args(cmd: &Command, matcher: &ArgMatcher) -> Self {
+        let mut potential = FlatMap::new();
+        potential.extend_unchecked(
+            matcher
+                .args()
+                .filter(|(_, matched)| matched.check_explicit(&ArgPredicate::IsPresent))
+                .map(|(id, _)| {
+                    let conf = gather_direct_conflicts(cmd, id);
+                    (id.clone(), conf)
+                }),
+        );
+        Self { potential }
     }
 
-    fn gather_conflicts(&mut self, cmd: &Command, matcher: &ArgMatcher, arg_id: &Id) -> Vec<Id> {
+    fn gather_conflicts(&self, cmd: &Command, arg_id: &Id) -> Vec<Id> {
         debug!("Conflicts::gather_conflicts: arg={:?}", arg_id);
         let mut conflicts = Vec::new();
-        for other_arg_id in matcher
-            .arg_ids()
-            .filter(|arg_id| matcher.check_explicit(arg_id, &ArgPredicate::IsPresent))
-        {
+
+        let arg_id_conflicts_storage;
+        let arg_id_conflicts = if let Some(arg_id_conflicts) = self.get_direct_conflicts(arg_id) {
+            arg_id_conflicts
+        } else {
+            // `is_missing_required_ok` is a case where we check not-present args for conflicts
+            arg_id_conflicts_storage = gather_direct_conflicts(cmd, arg_id);
+            &arg_id_conflicts_storage
+        };
+        for (other_arg_id, other_arg_id_conflicts) in self.potential.iter() {
             if arg_id == other_arg_id {
                 continue;
             }
 
-            if self
-                .gather_direct_conflicts(cmd, arg_id)
-                .contains(other_arg_id)
-            {
+            if arg_id_conflicts.contains(other_arg_id) {
                 conflicts.push(other_arg_id.clone());
             }
-            if self
-                .gather_direct_conflicts(cmd, other_arg_id)
-                .contains(arg_id)
-            {
+            if other_arg_id_conflicts.contains(arg_id) {
                 conflicts.push(other_arg_id.clone());
             }
         }
+
         debug!("Conflicts::gather_conflicts: conflicts={:?}", conflicts);
         conflicts
     }
 
-    fn gather_direct_conflicts(&mut self, cmd: &Command, arg_id: &Id) -> &[Id] {
-        self.potential.entry(arg_id.clone()).or_insert_with(|| {
-            let conf = if let Some(arg) = cmd.find(arg_id) {
-                let mut conf = arg.blacklist.clone();
-                for group_id in cmd.groups_for_arg(arg_id) {
-                    let group = cmd.find_group(&group_id).expect(INTERNAL_ERROR_MSG);
-                    conf.extend(group.conflicts.iter().cloned());
-                    if !group.multiple {
-                        for member_id in &group.args {
-                            if member_id != arg_id {
-                                conf.push(member_id.clone());
-                            }
-                        }
-                    }
-                }
-
-                // Overrides are implicitly conflicts
-                conf.extend(arg.overrides.iter().cloned());
-
-                conf
-            } else if let Some(group) = cmd.find_group(arg_id) {
-                group.conflicts.clone()
-            } else {
-                debug_assert!(false, "id={:?} is unknown", arg_id);
-                Vec::new()
-            };
-            debug!(
-                "Conflicts::gather_direct_conflicts id={:?}, conflicts={:?}",
-                arg_id, conf
-            );
-            conf
-        })
+    fn get_direct_conflicts(&self, arg_id: &Id) -> Option<&[Id]> {
+        self.potential.get(arg_id).map(Vec::as_slice)
     }
 }
 
+fn gather_direct_conflicts(cmd: &Command, id: &Id) -> Vec<Id> {
+    let conf = if let Some(arg) = cmd.find(id) {
+        gather_arg_direct_conflicts(cmd, arg)
+    } else if let Some(group) = cmd.find_group(id) {
+        gather_group_direct_conflicts(group)
+    } else {
+        debug_assert!(false, "id={id:?} is unknown");
+        Vec::new()
+    };
+    debug!("Conflicts::gather_direct_conflicts id={id:?}, conflicts={conf:?}",);
+    conf
+}
+
+fn gather_arg_direct_conflicts(cmd: &Command, arg: &Arg) -> Vec<Id> {
+    let mut conf = arg.blacklist.clone();
+    for group_id in cmd.groups_for_arg(arg.get_id()) {
+        let group = cmd.find_group(&group_id).expect(INTERNAL_ERROR_MSG);
+        conf.extend(group.conflicts.iter().cloned());
+        if !group.multiple {
+            for member_id in &group.args {
+                if member_id != arg.get_id() {
+                    conf.push(member_id.clone());
+                }
+            }
+        }
+    }
+
+    // Overrides are implicitly conflicts
+    conf.extend(arg.overrides.iter().cloned());
+
+    conf
+}
+
+fn gather_group_direct_conflicts(group: &ArgGroup) -> Vec<Id> {
+    group.conflicts.clone()
+}
+
 pub(crate) fn get_possible_values_cli(a: &Arg) -> Vec<PossibleValue> {
     if !a.is_takes_value_set() {
         vec![]
diff --git a/src/util/color.rs b/src/util/color.rs
index 7c7468e..5a0a8ce 100644
--- a/src/util/color.rs
+++ b/src/util/color.rs
@@ -82,7 +82,7 @@
                 return Ok(*variant);
             }
         }
-        Err(format!("Invalid variant: {}", s))
+        Err(format!("invalid variant: {s}"))
     }
 }
 
diff --git a/src/util/flat_map.rs b/src/util/flat_map.rs
index 7d689ab..468f0a9 100644
--- a/src/util/flat_map.rs
+++ b/src/util/flat_map.rs
@@ -69,7 +69,7 @@
             .keys
             .iter()
             .enumerate()
-            .find_map(|(i, k)| (k.borrow() == key).then(|| i)));
+            .find_map(|(i, k)| (k.borrow() == key).then_some(i)));
         let key = self.keys.remove(index);
         let value = self.values.remove(index);
         Some((key, value))
diff --git a/src/util/mod.rs b/src/util/mod.rs
index ed38fbc..e6a8f70 100644
--- a/src/util/mod.rs
+++ b/src/util/mod.rs
@@ -1,7 +1,7 @@
 #![allow(clippy::single_component_path_imports)]
 
-mod flat_map;
-mod flat_set;
+pub(crate) mod flat_map;
+pub(crate) mod flat_set;
 mod graph;
 mod id;
 mod str_to_bool;