Repository: rust
Issue: Stdlib proposal: AsPtr, IntoRawPtr, FromRawPtr
Labels: T-libs-api,C-feature-request

I'd like to propose some new conversion traits for `core::convert`: `AsPtr`, `IntoRawPtr`, `FromRawPtr`. These would be defined like so:

```rust
trait AsPtr {
    type Inner: ?Sized;
    fn as_ptr(&self) -> *const Self::Inner;
}

trait IntoRawPtr: Sized {
    type Inner: ?Sized;
    fn into_raw(self) -> *mut Self::Inner;
}

trait FromRawPtr: IntoRawPtr {
    // Safety: this must ONLY be called on a pointer that was received
    // through `into_raw`, and that pointer must immediately be discarded
    // afterwards
    unsafe fn from_raw(*mut Self::Inner) -> Self
}
```

These traits would be implemented for raw pointer types, as well as for smart pointer types like `Box`, `Arc`, `Weak`, etc. 

The purpose of these traits would, obviously, be to facilitate conversion of a type into and back out of a pointer. The motivating practical use case is to make it easier to create `RawWaker`s and associated implementations, especially through intermediate Handle types. Consider this example:

```rust
#[derive(Clone)]
struct MyWaker {
    state: Arc<State>,
}

impl MyWaker {
    fn wake(&self) { ... }
}
```

This would be *relatively* easy to create a RawWaker for, since we can directly convert the `state` `Arc` into and out of the requisite `*const()`, and write the vtable methods to convert it back into an `Arc`. However, now consider this example:

```rust
// Crate A:
#[derive(Clone)]
struct Unparker {
    state: Arc<State>
}

impl Unparker {
    fn unpark(&self) { ... }
}

// Crate B:
#[derive(Clone)]
struct MyWaker {
    state: Unparker
}

impl MyWaker {
    fn wake(&self) { self.state.unpark(); }
}
```

This would be impossible to create a `RawWaker` for, without:

- Boxing or Arcing the `Unparker` (adds an unnecessary level of indirection)
- transmuting the `Unparker` to and from `*const()` (unsafe, since it now depends on the private implementation details of `Unparker`).

However, with the proposed traits, if `Unparker` wanted to opt-in to being used in this way, it could:

```rust
impl IntoRawPtr for Unparker {
    type Inner = ();
    fn into_raw(self) -> *mut () {
        self.state.into_raw() as *mut()
    }
}

impl FromRawPtr for Unparker {
    unsafe fn from_raw(ptr: *mut ()) -> Self {
        Self { state: Arc::from_raw(ptr as *mut State) }
    }
}
```

This would allow the `Unparker` to declare its "pointer-ness" as part of its public API (without actually exposing any implementation details), enabling its use in `RawWaker` (and other raw pointer APIs, such as C FFI).

## Alternatives:

### Third party

These traits could, of course, be provided as a 3rd party crate, but I believe these traits are sufficiently "fundamental" (similar to `Into`/`From`, `AsRef`, etc) to warrant inclusion directly into the standard library. This would also help different, independent libraries to coordinate with each other through this trait, which is possible but more difficult (due to potential ecosystem fragmentation) with a third party crate. It's also the sort of thing that seems "too simple" to require an entire dependency crate.

### Existing traits

While we could use `Into` / `From`, I don't think that those provide a strong enough contract to ensure the correct use of these, especially `IntoRawPtr` and `FromRawPtr`. Additionally, a type should only be able to be converted through a single pointer type, so having a dedicated trait with an associated type makes the most sense.