rust/tests/ui/moves/nested-loop-moved-value-wrong-continue.rs
Esteban Küber 78d29ad8d6 Point at continue and break that might be in the wrong place
Sometimes move errors are because of a misplaced `continue`, but we didn't
surface that anywhere. Now when there are more than one set of nested loops
we show them out and point at the `continue` and `break` expressions within
that might need to go elsewhere.

```
error[E0382]: use of moved value: `foo`
  --> $DIR/nested-loop-moved-value-wrong-continue.rs:46:18
   |
LL |     for foo in foos {
   |         ---
   |         |
   |         this reinitialization might get skipped
   |         move occurs because `foo` has type `String`, which does not implement the `Copy` trait
...
LL |         for bar in &bars {
   |         ---------------- inside of this loop
...
LL |                 baz.push(foo);
   |                          --- value moved here, in previous iteration of loop
...
LL |         qux.push(foo);
   |                  ^^^ value used here after move
   |
note: verify that your loop breaking logic is correct
  --> $DIR/nested-loop-moved-value-wrong-continue.rs:41:17
   |
LL |     for foo in foos {
   |     ---------------
...
LL |         for bar in &bars {
   |         ----------------
...
LL |                 continue;
   |                 ^^^^^^^^ this `continue` advances the loop at line 33
help: consider moving the expression out of the loop so it is only moved once
   |
LL ~         let mut value = baz.push(foo);
LL ~         for bar in &bars {
LL |
 ...
LL |             if foo == *bar {
LL ~                 value;
   |
help: consider cloning the value if the performance cost is acceptable
   |
LL |                 baz.push(foo.clone());
   |                             ++++++++
```

Fix #92531.
2024-03-17 21:32:26 +00:00

51 lines
1.7 KiB
Rust

fn foo() {
let foos = vec![String::new()];
let bars = vec![""];
let mut baz = vec![];
let mut qux = vec![];
for foo in foos { for bar in &bars { if foo == *bar {
//~^ NOTE this reinitialization might get skipped
//~| NOTE move occurs because `foo` has type `String`
//~| NOTE inside of this loop
//~| HELP consider moving the expression out of the loop
//~| NOTE in this expansion of desugaring of `for` loop
baz.push(foo);
//~^ NOTE value moved here
//~| HELP consider cloning the value
continue;
//~^ NOTE verify that your loop breaking logic is correct
//~| NOTE this `continue` advances the loop at $DIR/nested-loop-moved-value-wrong-continue.rs:6:23
} }
qux.push(foo);
//~^ ERROR use of moved value
//~| NOTE value used here
}
}
fn main() {
let foos = vec![String::new()];
let bars = vec![""];
let mut baz = vec![];
let mut qux = vec![];
for foo in foos {
//~^ NOTE this reinitialization might get skipped
//~| NOTE move occurs because `foo` has type `String`
for bar in &bars {
//~^ NOTE inside of this loop
//~| HELP consider moving the expression out of the loop
//~| NOTE in this expansion of desugaring of `for` loop
if foo == *bar {
baz.push(foo);
//~^ NOTE value moved here
//~| HELP consider cloning the value
continue;
//~^ NOTE verify that your loop breaking logic is correct
//~| NOTE this `continue` advances the loop at line 33
}
}
qux.push(foo);
//~^ ERROR use of moved value
//~| NOTE value used here
}
}