Generic transmutability
- Dominant language
- Rust
- Stars
- 2.6k
- Forks
- 179
- Avg merge
- 1d 19h
- Merged PRs (30d)
- 29
Description
*See also: #1122*
Currently, we have a number of traits that express some aspect of transmutability:
- [`TransparentWrapper`](https://github.com/google/zerocopy/blob/76915d0978e68404d4e53181d462fcc341a71a39/src/util.rs#L45)
- [`AliasingSafe`](https://github.com/google/zerocopy/blob/76915d0978e68404d4e53181d462fcc341a71a39/src/pointer/aliasing_safety.rs#L27)
These, in turn, are used to bound certain `Ptr` transmutation methods, e.g.:
- [`transparent_wrapper_into_inner`](https://github.com/google/zerocopy/blob/76915d0978e68404d4e53181d462fcc341a71a39/src/pointer/ptr.rs#L560)
- [`as_bytes`](https://github.com/google/zerocopy/blob/76915d0978e68404d4e53181d462fcc341a71a39/src/pointer/ptr.rs#L1006)
- [`try_cast_into`](https://github.com/google/zerocopy/blob/76915d0978e68404d4e53181d462fcc341a71a39/src/pointer/ptr.rs#L1129)
Both `transparent_wrapper_into_inner` and `as_bytes` implement special cases of a generic `Ptr` to `Ptr` transmutation. This suggests that we could in theory support a more generic `Ptr::transmute` method, supported by a new `TransmutableFrom` trait. This trait would share some similarities with the [built-in transmutability trait](https://github.com/rust-lang/rust/issues/99571). However, as `TransparentWrapper`'s support for invariant variance shows, it might be *more* powerful than that trait in certain ways.
In its most basic form, this API would look something like:
```rust
unsafe trait TransmutableFrom {}
impl<'a, T, A: Aliasing> Ptr<'a, T, (A, Aligned, Valid)> {
fn transmute>(self) -> Ptr<'a, U, (A, Aligned, Valid)>
}
```
However, we will likely want to relax the `Aligned` and `Valid` requirements and post-conditions, and support a generic framework for mapping source invariants (on `T`) to destination invariants (on `U`) - essentially a generalization of what's currently supported with `TransparentWrapper`'s invariant variance concept.
There may be multiple overlapping reasons to support transmuting a particular pair of types. For example, we could imagine the following impls:
```rust
unsafe impl TransmutableFrom for U {}
unsafe impl TransmutableFrom for MaybeUninit {}
```
Currently, these would result in an impl conflict. If [`#[marker]` traits](https://github.com/rust-lang/rust/issues/29864) are stabilized, this won't be an issue - we can just mark `TransmutableFrom` as a `#[marker]` trait. Alternatively, we could use a dummy "reason" parameter to disambiguate, [as we do with `AliasingSafe` today](https://github.com/google/zerocopy/blob/76915d0978e68404d4e53181d462fcc341a71a39/src/pointer/aliasing_safety.rs#L27):
```rust
unsafe trait TransmutableFrom {}
enum BecauseIntoBytesFromBytes {}
enum BecauseMaybeUninit {}
unsafe impl TransmutableFrom for U {}
unsafe impl TransmutableFrom for MaybeUninit {}
```
Contributor guide
Assessment
This issue has not been assessed yet.