Description
I had code similar to the below (which is a minimal reproduction version of the original code), and its error was very confusing to me, enough so that I had to ask about what was wrong with it on the Rust discord, and even then it took a little while before anyone could get through to me what was even wrong.
Given the following code: https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=c437992df178c2e794b09b37cc3b2ea3
let foos = vec![String::from("hello"), String::from("world")];
let bars = vec!["world"];
let mut baz = vec![];
let mut qux = vec![];
for foo in foos {
for bar in &bars {
if foo == *bar {
baz.push(foo);
continue;
}
}
qux.push(foo);
}
The current output is:
error[E0382]: borrow of moved value: `foo`
--> src/main.rs:10:16
|
8 | for foo in foos {
| ---
| |
| this reinitialization might get skipped
| move occurs because `foo` has type `String`, which does not implement the `Copy` trait
9 | for bar in &bars {
10 | if foo == *bar {
| ^^^ value borrowed here after move
11 | baz.push(foo);
| --- value moved here, in previous iteration of loop
The problem was that I meant to continue
the outer loop, but I had forgotten that I was inside an inner loop. What made it all the more confusing is that it points to foo
in the outer loop and says "this reinitialization might get skipped," which baffled me, because I couldn't ever imagine a loop variable not being reinitialized when the next iteration comes around.
So the combination of "value moved here, in previous iteration of loop" combined with "this reinitialization might get skipped" made no sense to me.
I'm not really sure how this could be improved, but the fact that there are two loops involved makes this diagnostic confusing in my opinion. It might make sense to detect that such a situation is going on and be more careful about the wording, by saying something like "in previous iteration of inner loop."