The Rust book says that raw pointers "are considered sendable (if their contents is considered sendable)".
However from what I can see, the compiler generates the error the trait
core::marker::Sendis not implemented for the type
when it encounters a raw pointer to a Sendable type.
It could be that I am doing something wrong, it could be that the documentation is unclear or it could be that the error message isn't helpful at indicating whatever the real problem with this code is.
extern crate core;
use std::thread::Thread;
struct ShouldBeSendable {
x: i32
}
unsafe impl core::marker::Send for ShouldBeSendable { }
fn main() {
let sendablePtr : *const ShouldBeSendable = &ShouldBeSendable {x: 5};
let closure = move |:| {
*sendablePtr;
};
let something = Thread::spawn(closure);
}
Produces an error:
test.rs:15:21: 15:34 error: the trait `core::marker::Send` is not implemented for the type `*const ShouldBeSendable` [E0277]
test.rs:15 let something = Thread::spawn(closure);
^~~~~~~~~~~~~
test.rs:15:21: 15:34 note: `*const ShouldBeSendable` cannot be sent between threads safely
test.rs:15 let something = Thread::spawn(closure);
^~~~~~~~~~~~~
error: aborting due to previous error
$ rustc --version
rustc 1.0.0-dev (d15192317 2015-01-25 16:09:48 +0000)
This changed recently, leaving the docs out of date. Thanks for noticing and filing a bug!
@drewcrawford You can use the Unique
wrapper to make your raw pointer Send
able. This modified version of your code works:
use std::ptr::Unique;
use std::thread::Thread;
#[derive(Copy)]
struct ShouldBeSendable {
x: i32
}
unsafe impl std::marker::Send for ShouldBeSendable { }
fn main() {
let ptr : *mut ShouldBeSendable = &mut ShouldBeSendable {x: 5}; // this is not `Send`
let sendablePtr = Unique(ptr); // but this is!
let closure = move |:| {
// `sendablePtr` con be moved inside this closure
let ptr = sendablePtr.0; // unpack the raw pointer
println!("{}", unsafe { (*ptr).x })
};
let something = Thread::scoped(closure).join();
}
@japaric example for Rust 1.25 using NonNull
.
https://play.rust-lang.org/?gist=1ce2532a0eefc60695663c26faddebe1&version=stable
Most helpful comment
@japaric example for Rust 1.25 using
NonNull
.https://play.rust-lang.org/?gist=1ce2532a0eefc60695663c26faddebe1&version=stable