Summary
In a match, one of my arms has an if inside which consumes a variable. collapsible_match suggests collapsing the if into the match's condition, and even performs the fix, but the fix does not compile, since the if consumes a variable which is referrenced in other arms.
Lint Name
collapsible_match
Reproducer
I tried this code:
for item in <(pem::SectionKind, Vec<u8>) as PemObject>::pem_file_iter(path)? {
let (kind, der) = item?;
match kind {
pem::SectionKind::Certificate => {
certs.push(CertificateDer::from(der));
}
pem::SectionKind::EcPrivateKey => {
if raw_key.replace(PrivateKeyDer::Sec1(der.into())).is_some() {
bail!("multiple keys found in {}", path.to_string_lossy());
}
}
pem::SectionKind::PrivateKey => {
if raw_key.replace(PrivateKeyDer::Pkcs8(der.into())).is_some() {
bail!("multiple keys found in {}", path.to_string_lossy());
}
}
pem::SectionKind::RsaPrivateKey => {
if raw_key.replace(PrivateKeyDer::Pkcs1(der.into())).is_some() {
bail!("multiple keys found in {}", path.to_string_lossy());
}
}
_ => {}
}
}
I saw this happen:
> cargo clippy --allow-dirty --fix
Compiling pimsync v0.0.0 (/home/hugo/src/git.sr.ht/~whynothugo/pimsync)
warning: failed to automatically apply fixes suggested by rustc to crate `pimsync`
after fixes were automatically applied the compiler reported errors within these files:
* src/tls.rs
This likely indicates a bug in either rustc or cargo itself,
and we would appreciate a bug report! You're likely to see
a number of compiler warnings after this message which cargo
attempted to fix but failed. If you could open an issue at
https://github.com/rust-lang/rust-clippy/issues
quoting the full output of this command we'd be very appreciative!
Note that you may be able to make some more progress in the near-term
fixing code with the `--broken-code` flag
The following errors were reported:
error[E0382]: use of moved value: `der`
--> src/tls.rs:183:57
|
173 | let (kind, der) = item?;
| ---
| |
| this reinitialization might get skipped
| move occurs because `der` has type `std::vec::Vec<u8>`, which does not implement the `Copy` trait
...
179 | if raw_key.replace(PrivateKeyDer::Sec1(der.into())).is_some() => {
| ------ `der` moved due to this method call
...
183 | if raw_key.replace(PrivateKeyDer::Pkcs8(der.into())).is_some() => {
| ^^^ value used here after move
|
note: `std::convert::Into::into` takes ownership of the receiver `self`, which moves `der`
--> /rustc/59807616e1fa2540724bfbac14d7976d7e4a3860/library/core/src/convert/mod.rs:455:12
help: you can `clone` the value and consume it, but this might not be your desired behavior
|
179 | if raw_key.replace(PrivateKeyDer::Sec1(der.clone().into())).is_some() => {
| ++++++++
error[E0382]: use of moved value: `der`
--> src/tls.rs:187:57
|
173 | let (kind, der) = item?;
| ---
| |
| this reinitialization might get skipped
| move occurs because `der` has type `std::vec::Vec<u8>`, which does not implement the `Copy` trait
...
179 | if raw_key.replace(PrivateKeyDer::Sec1(der.into())).is_some() => {
| ------ `der` moved due to this method call
...
183 | if raw_key.replace(PrivateKeyDer::Pkcs8(der.into())).is_some() => {
| ------ `der` moved due to this method call
...
187 | if raw_key.replace(PrivateKeyDer::Pkcs1(der.into())).is_some() => {
| ^^^ value used here after move
|
help: you can `clone` the value and consume it, but this might not be your desired behavior
|
183 | if raw_key.replace(PrivateKeyDer::Pkcs8(der.clone().into())).is_some() => {
| ++++++++
help: you can `clone` the value and consume it, but this might not be your desired behavior
|
179 | if raw_key.replace(PrivateKeyDer::Sec1(der.clone().into())).is_some() => {
| ++++++++
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0382`.
Original diagnostics will follow.
warning: this `if` can be collapsed into the outer `match`
--> src/tls.rs:179:17
|
179 | / if raw_key.replace(PrivateKeyDer::Sec1(der.into())).is_some() {
180 | | bail!("multiple keys found in {}", path.to_string_lossy());
181 | | }
| |_________________^
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.95.0/index.html#collapsible_match
= note: `#[warn(clippy::collapsible_match)]` on by default
help: collapse nested if block
|
178 ~ pem::SectionKind::EcPrivateKey
179 ~ if raw_key.replace(PrivateKeyDer::Sec1(der.into())).is_some() => {
180 | bail!("multiple keys found in {}", path.to_string_lossy());
181 ~ }
|
warning: this `if` can be collapsed into the outer `match`
--> src/tls.rs:184:17
|
184 | / if raw_key.replace(PrivateKeyDer::Pkcs8(der.into())).is_some() {
185 | | bail!("multiple keys found in {}", path.to_string_lossy());
186 | | }
| |_________________^
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.95.0/index.html#collapsible_match
help: collapse nested if block
|
183 ~ pem::SectionKind::PrivateKey
184 ~ if raw_key.replace(PrivateKeyDer::Pkcs8(der.into())).is_some() => {
185 | bail!("multiple keys found in {}", path.to_string_lossy());
186 ~ }
|
warning: this `if` can be collapsed into the outer `match`
--> src/tls.rs:189:17
|
189 | / if raw_key.replace(PrivateKeyDer::Pkcs1(der.into())).is_some() {
190 | | bail!("multiple keys found in {}", path.to_string_lossy());
191 | | }
| |_________________^
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.95.0/index.html#collapsible_match
help: collapse nested if block
|
188 ~ pem::SectionKind::RsaPrivateKey
189 ~ if raw_key.replace(PrivateKeyDer::Pkcs1(der.into())).is_some() => {
190 | bail!("multiple keys found in {}", path.to_string_lossy());
191 ~ }
|
warning: `pimsync` (bin "pimsync") generated 3 warnings (run `cargo clippy --fix --bin "pimsync" -p pimsync -- --no-deps` to apply 3 suggestions)
Finished `dev` profile [unoptimized + debuginfo] target(s) in 1.10s
I expected to see this happen:
No warning; these conditions cannot be collapsed. This is a false positive, and the "fix" is invalid.
Version
rustc 1.95.0 (59807616e 2026-04-14) (Alpine Linux Rust 1.95.0-r0)
binary: rustc
commit-hash: 59807616e1fa2540724bfbac14d7976d7e4a3860
commit-date: 2026-04-14
host: x86_64-alpine-linux-musl
release: 1.95.0
LLVM version: 22.1.3
Additional Labels
Vaguely similar to #16903, although that issue is about mutable borrows and this one is about the variable being consumed.
Summary
In a
match, one of my arms has anifinside which consumes a variable.collapsible_matchsuggests collapsing theifinto thematch's condition, and even performs the fix, but the fix does not compile, since theifconsumes a variable which is referrenced in other arms.Lint Name
collapsible_match
Reproducer
I tried this code:
I saw this happen:
I expected to see this happen:
No warning; these conditions cannot be collapsed. This is a false positive, and the "fix" is invalid.
Version
Additional Labels
Vaguely similar to #16903, although that issue is about mutable borrows and this one is about the variable being consumed.