Open
Description
Summary
Clippy falsely reports a "redundant clone" warning. Removing the clone leads to a borrow of moved value
error.
This bug occurs on 1.70.0 as well as on nightly.
Reproducer
I tried this code:
fn generate_for_loop(ident: Variable, expr: Expression, body: Statement) -> String {
// Assign expression to variable to access it from within the loop
let mut expr_ident = ident.clone();
expr_ident.name = format!("loop_orig_{}", ident.name);
let mut out_str = format!("{};\n", generate_declare(&expr_ident, Some(expr)));
// Loop signature
out_str += &format!(
"for (let iter_{I} = 0; iter_{I} < {E}.length; iter_{I}++)",
I = ident.name,
E = expr_ident.name
);
// Block with prepended declaration of the actual variable
out_str += &generate_block(
body,
Some(format!(
"let {I} = {E}[iter_{I}];\n",
I = ident.name,
E = expr_ident.name,
)),
);
out_str
}
I expected to see this happen: The code to run successfully and apply fixes suggested by cargo clippy --fix
.
Instead, this happened: I encountered the following error:
warning: failed to automatically apply fixes suggested by rustc to crate `sb`
after fixes were automatically applied the compiler reported errors within these files:
* src/generator/js.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]: borrow of moved value: `ident`
--> src/generator/js.rs:188:47
|
185 | fn generate_for_loop(ident: Variable, expr: Expression, body: Statement) -> String {
| ----- move occurs because `ident` has type `ast::Variable`, which does not implement the `Copy` trait
186 | // Assign expression to variable to access it from within the loop
187 | let mut expr_ident = ident;
| ----- value moved here
188 | expr_ident.name = format!("loop_orig_{}", ident.name);
| ^^^^^^^^^^ value borrowed here after move
|
= note: this error originates in the macro `$crate::__export::format_args` which comes from the expansion of the macro `format` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider cloning the value if the performance cost is acceptable
|
187 | let mut expr_ident = ident.clone();
| ++++++++
error: aborting due to previous error
For more information about this error, try `rustc --explain E0382`.
Original diagnostics will follow.
warning: redundant clone
--> src/generator/js.rs:187:31
|
187 | let mut expr_ident = ident.clone();
| ^^^^^^^^ help: remove this
|
note: cloned value is neither consumed nor mutated
--> src/generator/js.rs:187:
26
|
187 | let mut expr_ident = ident.clone();
| ^^^^^^^^^^^^^
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#redundant_clone
= note: `#[warn(clippy::redundant_clone)]` on by default
warning: `antimony-lang` (bin "sb") generated 1 warning (run `cargo clippy --fix --bin "sb"` to apply 1 suggestion)
Version
rustc 1.72.0-nightly (df77afbca 2023-06-12)
binary: rustc
commit-hash: df77afbcaf3365a32066a8ca4a00ae6fc9a69647
commit-date: 2023-06-12
host: aarch64-apple-darwin
release: 1.72.0-nightly
LLVM version: 16.0.5
Additional Labels
@rustbot label +I-suggestion-causes-error
Activity
KisaragiEffective commentedon Jun 14, 2023
@rustbot label I-false-positive
ndrewxie commentedon Jun 14, 2023
Hmm, appears to have something to do with the format! macro.
The following snippet does NOT generate a redundant clone warning:
However, changing the return
ident.name
toformat!("{}", ident.name)
yields the desired lintMy (admittedly not-very-well-informed) theory is that the use of format! prevents clippy from noticing that both expr_ident and ident are being used - perhaps because the
format_args!
(whichformat!
calls) is a compiler built-in, so it likely doesn't expand to anything that clippy would notice as "using the value".I'd like to take a shot at this: @rustbot claim
Alexendoo commentedon Jun 14, 2023
Thanks for the small snippet. I think this is likely more complicated though, some of the other reports contain no macro calls - #10873
ndrewxie commentedon Jun 15, 2023
Aah I see, it is indeed more complicated. I made a code snippet that lets me "toggle" the error on and off by changing whether Asdf derives Copy or not:
And what I've found is that
visit_local_usage
is not detecting properly mutations to the cloned value... However, this is where the clippy codebase ends and the rustc codebase begins, which doesn't seem like something that would be buggy... So perhaps it's time to take a step back and see if I'm missing something 😅Attached is a snippet of the diff of some debug output for the case where Asdf is Copy (emits the redundant clone warning, on the left) vs the case where Asdf is not Copy (doesn't emit a warning, on the right):

(the debug line was added in
clippy_utils/src/mir/mod.rs::visit_local_usage
, inside of thetry_fold
, and just prints out the basic block ID and the basic block data).ndrewxie commentedon Jun 15, 2023
Just clicked through the issue you linked in more depth, and it appears y'all have already found the root issue. If there's anything left to do that I can help with, I'd love to join in, otherwise I'll just leave this here and find something else to do :)
bernardosulzbach commentedon Jun 25, 2023
This is hitting me particularly hard. I'm running
that I guess includes the recent move to nursery. Shouldn't that have removed the warning?
I also tested with a new Cargo project, and the warning is still present with my simplified reproduction below.
Do I need to manually disable this warning?
Alexendoo commentedon Jun 25, 2023
Nightly doesn't have that change yet, the
rust-lang/rust-clippy
->rust-lang/rust
sync is currently blocked (rust-lang/rust#112708), after that is resolved it will be in the nightly after the next syncIn the meanwhile yeah you can manually disable it
FirelightFlagboy commentedon Jul 11, 2023
I've a similar error with this sample code on rust
1.70.0
Here is the output of
cargo clippy -p redundant-clone --fix --allow-dirty
9 remaining items