forked from rust-lang/rust
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Detect when move of
!Copy
value occurs within loop
and should lik…
…ely not be cloned When encountering a move error on a value within a loop of any kind, identify if the moved value belongs to a call expression that should not be cloned and avoid the semantically incorrect suggestion. Also try to suggest moving the call expression outside of the loop instead. ``` error[E0382]: use of moved value: `vec` --> $DIR/recreating-value-in-loop-condition.rs:6:33 | LL | let vec = vec!["one", "two", "three"]; | --- move occurs because `vec` has type `Vec<&str>`, which does not implement the `Copy` trait LL | while let Some(item) = iter(vec).next() { | ----------------------------^^^-------- | | | | | value moved here, in previous iteration of loop | inside of this loop | note: consider changing this parameter type in function `iter` to borrow instead if owning the value isn't necessary --> $DIR/recreating-value-in-loop-condition.rs:1:17 | LL | fn iter<T>(vec: Vec<T>) -> impl Iterator<Item = T> { | ---- ^^^^^^ this parameter takes ownership of the value | | | in this function help: consider moving the expression out of the loop so it is only moved once | LL ~ let mut value = iter(vec); LL ~ while let Some(item) = value.next() { | ``` We use the presence of a `break` in the loop that would be affected by the moved value as a heuristic for "shouldn't be cloned". Fix rust-lang#121466.
- Loading branch information
Showing
13 changed files
with
441 additions
and
42 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,3 @@ | ||
//@ run-rustfix | ||
#![allow(dead_code)] | ||
|
||
struct Events<R>(R); | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
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; | ||
} | ||
} | ||
qux.push(foo); | ||
//~^ ERROR use of moved value | ||
//~| NOTE value used here | ||
} | ||
} |
35 changes: 35 additions & 0 deletions
35
tests/ui/moves/nested-loop-moved-value-wrong-continue.stderr
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
error[E0382]: use of moved value: `foo` | ||
--> $DIR/nested-loop-moved-value-wrong-continue.rs:20: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 | ||
| | ||
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()); | ||
| ++++++++ | ||
|
||
error: aborting due to 1 previous error | ||
|
||
For more information about this error, try `rustc --explain E0382`. |
Oops, something went wrong.