google / google/zerocopy

Generic transmutability

Open
#1,359 0 comments 0 reactions 0 assignees View on GitHub
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

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.