Repository: clap-rs/clap (language: rust)

Issue:
`clippy::almost_swapped` check failing on latest nightly
### Please complete the following tasks

- [X] I have searched the [discussions](https://github.com/clap-rs/clap/discussions)
- [X] I have searched the [open](https://github.com/clap-rs/clap/issues) and [rejected](https://github.com/clap-rs/clap/issues?q=is%3Aissue+label%3AS-wont-fix+is%3Aclosed) issues

### Rust Version

rustc 1.69.0-nightly (d962ea578 2023-02-26)

### Clap Version

4.1.4

### Minimal reproducible code

```rust
use clap::Parser;

#[derive(Parser, Debug)]
struct SomeArgs {
    name: Vec<String>,
}
```


### Steps to reproduce the bug with the above code

`cargo clippy`

### Actual Behaviour

```sh
$ cargo clippy 
    Checking `<project>` v0.1.0 (`<path>`)
error: this looks like you are trying to swap `arg` and `name: Vec<String>`
 --> src/main.rs:5:5
  |
5 |     name: Vec<String>,
  |     ^^^^^^^^^^^^^^^^^ help: try: `std::mem::swap(&mut arg, &mut name: Vec<String>)`
  |
  = note: or maybe you should use `std::mem::replace`?
  = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#almost_swapped
note: the lint level is defined here
 --> src/main.rs:3:10
  |
3 | #[derive(Parser, Debug)]
  |          ^^^^^^
  = note: `#[deny(clippy::almost_swapped)]` implied by `#[deny(clippy::correctness)]`
  = note: this error originates in the derive macro `Parser` (in Nightly builds, run with -Z macro-backtrace for more info)

error: could not compile `<project>` due to previous error
```

### Expected Behaviour

No clippy errors

### Additional Context

```sh
$ cargo expand
```

```rust
#![feature(prelude_import)]
#[prelude_import]
use std::prelude::rust_2021::*;
#[macro_use]
extern crate std;
use clap::Parser;
struct SomeArgs {
    name: Vec<String>,
}
impl clap::Parser for SomeArgs {}
#[allow(dead_code, unreachable_code, unused_variables, unused_braces)]
#[allow(
    clippy::style,
    clippy::complexity,
    clippy::pedantic,
    clippy::restriction,
    clippy::perf,
    clippy::deprecated,
    clippy::nursery,
    clippy::cargo,
    clippy::suspicious_else_formatting,
)]
#[deny(clippy::correctness)]
impl clap::CommandFactory for SomeArgs {
    fn command<'b>() -> clap::Command {
        let __clap_app = clap::Command::new("op-reth");
        <Self as clap::Args>::augment_args(__clap_app)
    }
    fn command_for_update<'b>() -> clap::Command {
        let __clap_app = clap::Command::new("op-reth");
        <Self as clap::Args>::augment_args_for_update(__clap_app)
    }
}
#[allow(dead_code, unreachable_code, unused_variables, unused_braces)]
#[allow(
    clippy::style,
    clippy::complexity,
    clippy::pedantic,
    clippy::restriction,
    clippy::perf,
    clippy::deprecated,
    clippy::nursery,
    clippy::cargo,
    clippy::suspicious_else_formatting,
)]
#[deny(clippy::correctness)]
impl clap::FromArgMatches for SomeArgs {
    fn from_arg_matches(
        __clap_arg_matches: &clap::ArgMatches,
    ) -> ::std::result::Result<Self, clap::Error> {
        Self::from_arg_matches_mut(&mut __clap_arg_matches.clone())
    }
    fn from_arg_matches_mut(
        __clap_arg_matches: &mut clap::ArgMatches,
    ) -> ::std::result::Result<Self, clap::Error> {
        #![allow(deprecated)]
        let v = SomeArgs {
            name: __clap_arg_matches
                .remove_many::<String>("name")
                .map(|v| v.collect::<Vec<_>>())
                .unwrap_or_else(Vec::new),
        };
        ::std::result::Result::Ok(v)
    }
    fn update_from_arg_matches(
        &mut self,
        __clap_arg_matches: &clap::ArgMatches,
    ) -> ::std::result::Result<(), clap::Error> {
        self.update_from_arg_matches_mut(&mut __clap_arg_matches.clone())
    }
    fn update_from_arg_matches_mut(
        &mut self,
        __clap_arg_matches: &mut clap::ArgMatches,
    ) -> ::std::result::Result<(), clap::Error> {
        #![allow(deprecated)]
        if __clap_arg_matches.contains_id("name") {
            #[allow(non_snake_case)]
            let name = &mut self.name;
            *name = __clap_arg_matches
                .remove_many::<String>("name")
                .map(|v| v.collect::<Vec<_>>())
                .unwrap_or_else(Vec::new);
        }
        ::std::result::Result::Ok(())
    }
}
#[allow(dead_code, unreachable_code, unused_variables, unused_braces)]
#[allow(
    clippy::style,
    clippy::complexity,
    clippy::pedantic,
    clippy::restriction,
    clippy::perf,
    clippy::deprecated,
    clippy::nursery,
    clippy::cargo,
    clippy::suspicious_else_formatting,
)]
#[deny(clippy::correctness)]
impl clap::Args for SomeArgs {
    fn group_id() -> Option<clap::Id> {
        Some(clap::Id::from("SomeArgs"))
    }
    fn augment_args<'b>(__clap_app: clap::Command) -> clap::Command {
        {
            let __clap_app = __clap_app
                .group(
                    clap::ArgGroup::new("SomeArgs")
                        .multiple(true)
                        .args({
                            let members: [clap::Id; 1usize] = [clap::Id::from("name")];
                            members
                        }),
                );
            let __clap_app = __clap_app
                .arg({
                    #[allow(deprecated)]
                    let arg = clap::Arg::new("name")
                        .value_name("NAME")
                        .num_args(1..)
                        .value_parser({
                            use ::clap::builder::via_prelude::*;
                            let auto = ::clap::builder::_AutoValueParser::<
                                String,
                            >::new();
                            (&&&&&&auto).value_parser()
                        })
                        .action(clap::ArgAction::Append);
                    let arg = arg;
                    let arg = arg;
                    arg
                });
            __clap_app
        }
    }
    fn augment_args_for_update<'b>(__clap_app: clap::Command) -> clap::Command {
        {
            let __clap_app = __clap_app
                .group(
                    clap::ArgGroup::new("SomeArgs")
                        .multiple(true)
                        .args({
                            let members: [clap::Id; 1usize] = [clap::Id::from("name")];
                            members
                        }),
                );
            let __clap_app = __clap_app
                .arg({
                    #[allow(deprecated)]
                    let arg = clap::Arg::new("name")
                        .value_name("NAME")
                        .num_args(1..)
                        .value_parser({
                            use ::clap::builder::via_prelude::*;
                            let auto = ::clap::builder::_AutoValueParser::<
                                String,
                            >::new();
                            (&&&&&&auto).value_parser()
                        })
                        .action(clap::ArgAction::Append);
                    let arg = arg;
                    let arg = arg.required(false);
                    arg
                });
            __clap_app
        }
    }
}
#[automatically_derived]
impl ::core::fmt::Debug for SomeArgs {
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field1_finish(
            f,
            "SomeArgs",
            "name",
            &&self.name,
        )
    }
}
```

### Debug Output

_No response_


Discussion / hints:
There is a similar error with subcommands:

```rust
#[derive(clap::Subcommand)]
enum Command {
    X
}
```

results in:

```
error: this looks like you are trying to swap `__clap_subcommand` and `clap::Subcommand`
 --> src/lib.rs:3:10
  |
3 | #[derive(clap::Subcommand)]
  |          ^^^^^^^^^^^^^^^^
  |
  = note: or maybe you should use `std::mem::replace`?
  = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#almost_swapped
note: the lint level is defined here
 --> src/lib.rs:3:10
  |
3 | #[derive(clap::Subcommand)]
  |          ^^^^^^^^^^^^^^^^
  = note: `#[deny(clippy::almost_swapped)]` implied by `#[deny(clippy::correctness)]`
  = note: this error originates in the derive macro `clap::Subcommand` (in Nightly builds, run with -Z macro-backtrace for more info)
```

The relevant part of the expansion seems to be:

```rust
impl clap::Subcommand for Command {
    fn augment_subcommands<'b>(__clap_app: clap::Command) -> clap::Command {
        ;
        let __clap_app = __clap_app;
        let __clap_app =
            __clap_app.subcommand({
                    let __clap_subcommand = clap::Command::new("x");
                    let __clap_subcommand = __clap_subcommand;
                    let __clap_subcommand = __clap_subcommand;
                    __clap_subcommand
                });
        ;
        __clap_app
    }
    fn augment_subcommands_for_update<'b>(__clap_app: clap::Command)
        -> clap::Command {
        ;
        let __clap_app = __clap_app;
        let __clap_app =
            __clap_app.subcommand({
                    let __clap_subcommand = clap::Command::new("x");
                    let __clap_subcommand = __clap_subcommand;
                    let __clap_subcommand = __clap_subcommand;
                    __clap_subcommand
                });
        ;
        __clap_app
    }
    fn has_subcommand(__clap_name: &str) -> bool {
        if "x" == __clap_name { return true }
        false
    }
}
```
@Ltrlg ty, this should be fixed in https://github.com/clap-rs/clap/pull/4735/commits/c1caf462ce40fc541066dfb2a9cccb586777a757 as well

Fix patch:
diff --git a/clap_derive/src/derives/args.rs b/clap_derive/src/derives/args.rs
index b5d51bfca39..d019cd7a578 100644
--- a/clap_derive/src/derives/args.rs
+++ b/clap_derive/src/derives/args.rs
@@ -109,6 +109,7 @@ pub fn gen_for_struct(
             clippy::nursery,
             clippy::cargo,
             clippy::suspicious_else_formatting,
+            clippy::almost_swapped,
         )]
         #[deny(clippy::correctness)]
         impl #impl_generics clap::FromArgMatches for #item_name #ty_generics #where_clause {
@@ -144,6 +145,7 @@ pub fn gen_for_struct(
             clippy::nursery,
             clippy::cargo,
             clippy::suspicious_else_formatting,
+            clippy::almost_swapped,
         )]
         #[deny(clippy::correctness)]
         impl #impl_generics clap::Args for #item_name #ty_generics #where_clause {
diff --git a/clap_derive/src/derives/into_app.rs b/clap_derive/src/derives/into_app.rs
index a45667ab296..4241ac0e7dd 100644
--- a/clap_derive/src/derives/into_app.rs
+++ b/clap_derive/src/derives/into_app.rs
@@ -36,6 +36,7 @@ pub fn gen_for_struct(item: &Item, item_name: &Ident, generics: &Generics) -> To
             clippy::nursery,
             clippy::cargo,
             clippy::suspicious_else_formatting,
+            clippy::almost_swapped,
         )]
         #[deny(clippy::correctness)]
         impl #impl_generics clap::CommandFactory for #item_name #ty_generics #where_clause {
@@ -72,6 +73,7 @@ pub fn gen_for_enum(item: &Item, item_name: &Ident, generics: &Generics) -> Toke
             clippy::nursery,
             clippy::cargo,
             clippy::suspicious_else_formatting,
+            clippy::almost_swapped,
         )]
         #[deny(clippy::correctness)]
         impl #impl_generics clap::CommandFactory for #item_name #ty_generics #where_clause {
diff --git a/clap_derive/src/derives/subcommand.rs b/clap_derive/src/derives/subcommand.rs
index 8a44e0c4219..e5bf16dec9c 100644
--- a/clap_derive/src/derives/subcommand.rs
+++ b/clap_derive/src/derives/subcommand.rs
@@ -80,6 +80,7 @@ pub fn gen_for_enum(
             clippy::nursery,
             clippy::cargo,
             clippy::suspicious_else_formatting,
+            clippy::almost_swapped,
         )]
         #[deny(clippy::correctness)]
         impl #impl_generics clap::FromArgMatches for #item_name #ty_generics #where_clause {
@@ -106,6 +107,7 @@ pub fn gen_for_enum(
             clippy::nursery,
             clippy::cargo,
             clippy::suspicious_else_formatting,
+            clippy::almost_swapped,
         )]
         #[deny(clippy::correctness)]
         impl #impl_generics clap::Subcommand for #item_name #ty_generics #where_clause {
diff --git a/clap_derive/src/derives/value_enum.rs b/clap_derive/src/derives/value_enum.rs
index a1411d02ab0..1e2daf3965d 100644
--- a/clap_derive/src/derives/value_enum.rs
+++ b/clap_derive/src/derives/value_enum.rs
@@ -65,6 +65,7 @@ pub fn gen_for_enum(item: &Item, item_name: &Ident, variants: &[(&Variant, Item)
             clippy::nursery,
             clippy::cargo,
             clippy::suspicious_else_formatting,
+            clippy::almost_swapped,
         )]
         #[deny(clippy::correctness)]
         impl clap::ValueEnum for #item_name {


Test patch: