Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4521,7 +4521,9 @@ struct BreakFinder {
impl<'hir> Visitor<'hir> for BreakFinder {
fn visit_expr(&mut self, ex: &'hir hir::Expr<'hir>) {
match ex.kind {
hir::ExprKind::Break(destination, _) => {
hir::ExprKind::Break(destination, _)
if !ex.span.is_desugaring(DesugaringKind::ForLoop) =>
{
self.found_breaks.push((destination, ex.span));
}
hir::ExprKind::Continue(destination) => {
Expand Down
10 changes: 0 additions & 10 deletions tests/ui/ergonomic-clones/closure/spawn-thread.edition2018.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,6 @@ LL | | drop((x.0, x.1, x.2));
| | --- use occurs due to use in closure
LL | | });
| |_________- value moved here, in previous iteration of loop
|
help: consider moving the expression out of the loop so it is only moved once
|
LL ~ let mut value = std::thread::spawn(use || {
LL +
LL + drop((x.0, x.1, x.2));
LL + });
LL ~ for _ in 0..10 {
LL ~ let handler = value;
|

error: aborting due to 1 previous error

Expand Down
37 changes: 37 additions & 0 deletions tests/ui/moves/arc-consumed-in-looped-closure.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
use std::thread;
use std::sync::{Arc, Mutex, Condvar};
use std::collections::VecDeque;

type Job = Box<dyn FnOnce() + Send + 'static>;

struct ThreadPool {
workers: Vec<thread::JoinHandle<()>>,
queue: Arc<()>,
}

impl ThreadPool {
fn execute<F>(&self, f: F)
where
F: FnOnce() + Send + 'static,
{
panic!()
}
}

fn main() {
let results = Arc::new(Mutex::new(Vec::new())); //~ NOTE move occurs because
let pool = ThreadPool {
workers: vec![],
queue: Arc::new(()),
};

for i in 0..20 { //~ NOTE inside of this loop
// let results = Arc::clone(&results); // Forgot this.
pool.execute(move || { //~ ERROR E0382
//~^ NOTE value moved into closure here, in previous iteration of loop
//~| HELP consider cloning the value before moving it into the closure
let mut r = results.lock().unwrap(); //~ NOTE use occurs due to use in closure
r.push(i);
});
}
}
27 changes: 27 additions & 0 deletions tests/ui/moves/arc-consumed-in-looped-closure.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
error[E0382]: use of moved value: `results`
--> $DIR/arc-consumed-in-looped-closure.rs:30:22
|
LL | let results = Arc::new(Mutex::new(Vec::new()));
| ------- move occurs because `results` has type `Arc<std::sync::Mutex<Vec<i32>>>`, which does not implement the `Copy` trait
...
LL | for i in 0..20 {
| -------------- inside of this loop
LL | // let results = Arc::clone(&results); // Forgot this.
LL | pool.execute(move || {
| ^^^^^^^ value moved into closure here, in previous iteration of loop
...
LL | let mut r = results.lock().unwrap();
| ------- use occurs due to use in closure
|
help: consider cloning the value before moving it into the closure
|
LL ~ let value = results.clone();
LL ~ pool.execute(move || {
LL |
LL |
LL ~ let mut r = value.lock().unwrap();
|

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0382`.
6 changes: 1 addition & 5 deletions tests/ui/moves/nested-loop-moved-value-wrong-continue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@ fn foo() {
//~^ 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
//~| NOTE
//~| NOTE
baz.push(foo);
Expand All @@ -35,16 +33,14 @@ fn main() {
//~| NOTE
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
//~| NOTE
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 36
//~| NOTE this `continue` advances the loop at line 34
}
}
qux.push(foo);
Expand Down
30 changes: 6 additions & 24 deletions tests/ui/moves/nested-loop-moved-value-wrong-continue.stderr
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
error[E0382]: use of moved value: `foo`
--> $DIR/nested-loop-moved-value-wrong-continue.rs:21:14
--> $DIR/nested-loop-moved-value-wrong-continue.rs:19:14
|
LL | for foo in foos { for bar in &bars { if foo == *bar {
| --- ---------------- inside of this loop
Expand All @@ -14,29 +14,20 @@ 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:17:9
--> $DIR/nested-loop-moved-value-wrong-continue.rs:15:9
|
LL | for foo in foos { for bar in &bars { if foo == *bar {
| --------------- ----------------
...
LL | continue;
| ^^^^^^^^ this `continue` advances the loop at $DIR/nested-loop-moved-value-wrong-continue.rs:6:23: 20:8
help: consider moving the expression out of the loop so it is only moved once
|
LL ~ for foo in foos { let mut value = baz.push(foo);
LL ~ for bar in &bars { if foo == *bar {
LL |
...
LL |
LL ~ value;
|
| ^^^^^^^^ this `continue` advances the loop at $DIR/nested-loop-moved-value-wrong-continue.rs:6:23: 18:8
help: consider cloning the value if the performance cost is acceptable
|
LL | baz.push(foo.clone());
| ++++++++

error[E0382]: use of moved value: `foo`
--> $DIR/nested-loop-moved-value-wrong-continue.rs:50:18
--> $DIR/nested-loop-moved-value-wrong-continue.rs:46:18
|
LL | for foo in foos {
| ---
Expand All @@ -54,7 +45,7 @@ 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:45:17
--> $DIR/nested-loop-moved-value-wrong-continue.rs:41:17
|
LL | for foo in foos {
| ---------------
Expand All @@ -63,16 +54,7 @@ LL | for bar in &bars {
| ----------------
...
LL | continue;
| ^^^^^^^^ this `continue` advances the loop at line 36
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;
|
| ^^^^^^^^ this `continue` advances the loop at line 34
help: consider cloning the value if the performance cost is acceptable
|
LL | baz.push(foo.clone());
Expand Down
Loading