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
1 change: 1 addition & 0 deletions library/alloc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@
#![feature(core_intrinsics)]
#![feature(deprecated_suggestion)]
#![feature(deref_pure_trait)]
#![feature(diagnostic_on_move)]
#![feature(dispatch_from_dyn)]
#![feature(ergonomic_clones)]
#![feature(error_generic_member_access)]
Expand Down
5 changes: 5 additions & 0 deletions library/alloc/src/sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,11 @@ macro_rules! acquire {
#[rustc_diagnostic_item = "Arc"]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_insignificant_dtor]
#[diagnostic::on_move(
message = "the type `{Self}` does not implement `Copy`",
label = "this move could be avoided by cloning the original `{Self}`, which is inexpensive",
note = "consider using `Arc::clone`"
)]
pub struct Arc<
T: ?Sized,
#[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global,
Expand Down
3 changes: 2 additions & 1 deletion tests/ui/moves/arc-consumed-in-looped-closure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ impl ThreadPool {
}

fn main() {
let results = Arc::new(Mutex::new(Vec::new())); //~ NOTE move occurs because
let results = Arc::new(Mutex::new(Vec::new())); //~ NOTE this move could be avoided by cloning the original `Arc`, which is inexpensive
let pool = ThreadPool {
workers: vec![],
queue: Arc::new(()),
Expand All @@ -29,6 +29,7 @@ fn main() {
// let results = Arc::clone(&results); // Forgot this.
pool.execute(move || { //~ ERROR E0382
//~^ NOTE value moved into closure here, in previous iteration of loop
//~| NOTE consider using `Arc::clone`
//~| 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);
Expand Down
6 changes: 4 additions & 2 deletions tests/ui/moves/arc-consumed-in-looped-closure.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
error[E0382]: use of moved value: `results`
error[E0382]: the type `Arc` does not implement `Copy`
--> $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
| ------- this move could be avoided by cloning the original `Arc`, which is inexpensive
...
LL | for i in 0..20 {
| -------------- inside of this loop
Expand All @@ -13,12 +13,14 @@ LL | pool.execute(move || {
LL | let mut r = results.lock().unwrap();
| ------- use occurs due to use in closure
|
= note: consider using `Arc::clone`
help: consider cloning the value before moving it into the closure
|
LL ~ let value = results.clone();
LL ~ pool.execute(move || {
LL |
LL |
LL |
LL ~ let mut r = value.lock().unwrap();
|

Expand Down
2 changes: 1 addition & 1 deletion tests/ui/moves/no-capture-arc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ fn main() {
assert_eq!((*arc_v)[3], 4);
});

assert_eq!((*arc_v)[2], 3); //~ ERROR borrow of moved value: `arc_v`
assert_eq!((*arc_v)[2], 3); //~ ERROR the type `Arc` does not implement `Copy`

println!("{:?}", *arc_v);
}
5 changes: 3 additions & 2 deletions tests/ui/moves/no-capture-arc.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
error[E0382]: borrow of moved value: `arc_v`
error[E0382]: the type `Arc` does not implement `Copy`
--> $DIR/no-capture-arc.rs:12:18
|
LL | let arc_v = Arc::new(v);
| ----- move occurs because `arc_v` has type `Arc<Vec<i32>>`, which does not implement the `Copy` trait
| ----- this move could be avoided by cloning the original `Arc`, which is inexpensive
LL |
LL | thread::spawn(move|| {
| ------ value moved into closure here
Expand All @@ -12,6 +12,7 @@ LL | assert_eq!((*arc_v)[3], 4);
LL | assert_eq!((*arc_v)[2], 3);
| ^^^^^ value borrowed here after move
|
= note: consider using `Arc::clone`
= note: borrow occurs due to deref coercion to `Vec<i32>`
help: consider cloning the value before moving it into the closure
|
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/moves/no-reuse-move-arc.fixed
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ fn main() {
assert_eq!((*value)[3], 4);
});

assert_eq!((*arc_v)[2], 3); //~ ERROR borrow of moved value: `arc_v`
assert_eq!((*arc_v)[2], 3); //~ ERROR the type `Arc` does not implement `Copy`

println!("{:?}", *arc_v);
}
2 changes: 1 addition & 1 deletion tests/ui/moves/no-reuse-move-arc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ fn main() {
assert_eq!((*arc_v)[3], 4);
});

assert_eq!((*arc_v)[2], 3); //~ ERROR borrow of moved value: `arc_v`
assert_eq!((*arc_v)[2], 3); //~ ERROR the type `Arc` does not implement `Copy`

println!("{:?}", *arc_v);
}
5 changes: 3 additions & 2 deletions tests/ui/moves/no-reuse-move-arc.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
error[E0382]: borrow of moved value: `arc_v`
error[E0382]: the type `Arc` does not implement `Copy`
--> $DIR/no-reuse-move-arc.rs:13:18
|
LL | let arc_v = Arc::new(v);
| ----- move occurs because `arc_v` has type `Arc<Vec<i32>>`, which does not implement the `Copy` trait
| ----- this move could be avoided by cloning the original `Arc`, which is inexpensive
LL |
LL | thread::spawn(move|| {
| ------ value moved into closure here
Expand All @@ -12,6 +12,7 @@ LL | assert_eq!((*arc_v)[3], 4);
LL | assert_eq!((*arc_v)[2], 3);
| ^^^^^ value borrowed here after move
|
= note: consider using `Arc::clone`
= note: borrow occurs due to deref coercion to `Vec<i32>`
help: consider cloning the value before moving it into the closure
|
Expand Down
Loading