Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

core::marker::Send and raw pointers #21709

Closed
drewcrawford opened this issue Jan 28, 2015 · 3 comments · Fixed by #23531
Closed

core::marker::Send and raw pointers #21709

drewcrawford opened this issue Jan 28, 2015 · 3 comments · Fixed by #23531

Comments

@drewcrawford
Copy link
Contributor

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::Send is 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)
@huonw huonw added the A-docs label Jan 28, 2015
@huonw
Copy link
Member

huonw commented Jan 28, 2015

This changed recently, leaving the docs out of date. Thanks for noticing and filing a bug!

@japaric
Copy link
Member

japaric commented Jan 28, 2015

@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();
}

@rubenrua
Copy link
Contributor

@japaric example for Rust 1.25 using NonNull.

https://play.rust-lang.org/?gist=1ce2532a0eefc60695663c26faddebe1&version=stable

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants