Misc 10 @jdonszelmann
use std::future::Future;
struct ThreadSafePtr<T>(pub *const T);
unsafe impl<T> Send for ThreadSafePtr<T> {}
fn requires_send(_f: impl Future + Send) {}
fn main() {
let x = 10;
let y = ThreadSafePtr(&raw const x);
requires_send(async move {
println!("{}", unsafe{*y.0})
})
}
Solution
error[E0277]: `*const i32` cannot be sent between threads safely
--> examples/misc_10.rs:12:19
|
12 | requires_send(async move {
| ------------- ^---------
| | |
| _____|_____________within this `{async block@examples/misc_10.rs:12:19: 12:29}`
| | |
| | required by a bound introduced by this call
13 | | println!("{}", unsafe{*y.0})
14 | | })
| |_____^ `*const i32` cannot be sent between threads safely
|
= help: within `{async block@examples/misc_10.rs:12:19: 12:29}`, the trait `Send` is not implemented for `*const i32`
note: required because it's used within this `async` block
--> examples/misc_10.rs:12:19
|
12 | requires_send(async move {
| ^^^^^^^^^^
note: required by a bound in `requires_send`
--> examples/misc_10.rs:6:36
|
6 | fn requires_send(_f: impl Future + Send) {}
| ^^^^ required by this bound in `requires_send`
For more information about this error, try `rustc --explain E0277`.
error: could not compile `code` (example "misc_10") due to 1 previous error
Despite the closure being move
, not the whole ThreadSafePtr
is moved into the async
block. Rust allows us to move different fields of a struct into different closures or async blocks. Since we only access y.0
, it only moves that field, which is a *const T
, which is not Send
, which means this code doesn't compile.
A slightly comical way to fix it is like this:
use std::future::Future;
struct ThreadSafePtr<T>(pub *const T);
unsafe impl<T> Send for ThreadSafePtr<T> {}
fn requires_send(_f: impl Future + Send) {}
fn main() {
let x = 10;
let y = ThreadSafePtr(&raw const x);
requires_send(async move {
let y = y; // <-- ADD THIS
println!("{}", unsafe{*y.0})
})
}
Note, before edition 2021, this kind of splitting was not possible and y
would be moved into the closure as a whole.