Rust: core::marker::Send and raw pointers

Created on 28 Jan 2015  ·  3Comments  ·  Source: rust-lang/rust

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 traitcore::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)

Most helpful comment

All 3 comments

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 Sendable. 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();
}
Was this page helpful?
0 / 5 - 0 ratings