Better error reporting for Sync and type that impl !Sync
2a60d64
Opened by Paul FLORENCE at
It would make a lot more sense if when a type impl !Sync the compiler could report an other error than the error that comes from this impl block.
For example, take a look at this code :
use std::sync::mpsc::channel;
use std::thread;
struct Foo {}
impl Foo {
fn do_something(&self) {
println!("hello");
}
}
fn main() {
let (tx, rx) = channel::<Foo>();
thread::spawn(move || rx.iter().map(|f| f.do_something()));
}
Which outputs :
17 | thread::spawn(move || rx.iter().map(|f| f.do_something()));
| ^^^^^^^^^^^^^ `std::sync::mpsc::Receiver<Foo>` cannot be shared between threads safely
|
= help: the trait `std::marker::Sync` is not implemented for `std::sync::mpsc::Receiver<Foo>`
= note: required because of the requirements on the impl of `std::marker::Send` for `&std::sync::mpsc::Receiver<Foo>`
= note: required because it appears within the type `std::sync::mpsc::Iter<'_, Foo>`
= note: required because it appears within the type `std::iter::Map<std::sync::mpsc::Iter<'_, Foo>, [closure@src/main.rs:17:41: 17:61]>`
= note: required by `std::thread::spawn`
It would be way better if it could just say that Receiver is explicitly not Sync.
I know that this a bad example because the error is actually due to the fact that the compiler does not move rx because we are returning a value from the call to map(), but it was the only one that I had...
Triage: no change.
Esteban Kuber at 2020-02-14 09:25:36
Current output:
error[E0277]: `std::sync::mpsc::Receiver<Foo>` cannot be shared between threads safely --> f80.rs:14:5 | 14 | thread::spawn(move || rx.iter().map(|f| f.do_something())); | ^^^^^^^^^^^^^ `std::sync::mpsc::Receiver<Foo>` cannot be shared between threads safely | = help: the trait `Sync` is not implemented for `std::sync::mpsc::Receiver<Foo>` = note: required for `&std::sync::mpsc::Receiver<Foo>` to implement `Send` note: required because it appears within the type `Iter<'_, Foo>` --> /home/gh-estebank/rust/library/std/src/sync/mpsc/mod.rs:225:12 | 225 | pub struct Iter<'a, T: 'a> { | ^^^^ note: required because it appears within the type `Map<Iter<'_, Foo>, {closure@f80.rs:14:41}>` --> /home/gh-estebank/rust/library/core/src/iter/adapters/map.rs:61:12 | 61 | pub struct Map<I, F> { | ^^^ note: required by a bound in `spawn` --> /home/gh-estebank/rust/library/std/src/thread/mod.rs:684:8 | 680 | pub fn spawn<F, T>(f: F) -> JoinHandle<T> | ----- required by a bound in this function ... 684 | T: Send + 'static, | ^^^^ required by this bound in `spawn`Esteban Kuber at 2023-10-20 20:12:45