mirror of
https://github.com/rust-lang/rust.git
synced 2026-04-27 18:57:42 +03:00
Introduce #[diagnostic::on_move] on Arc
This annotates the `Arc` type with the diagnostic attribute `#[diagnostic::on_move]`. Now when a moved `Arc` is borrowed, a suggestion to clone it is made, with a label explaining why.
This commit is contained in:
@@ -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)]
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -19,7 +19,7 @@ fn execute<F>(&self, f: F)
|
||||
}
|
||||
|
||||
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(()),
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
@@ -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();
|
||||
|
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
|
||||
|
||||
Reference in New Issue
Block a user