Extend `Ptr` to store unboxed values
- Dominant language
- Rust
- Stars
- 2.6k
- Forks
- 179
- Avg merge
- 1d 19h
- Merged PRs (30d)
- 29
Description
## Overview
Extend `Ptr` to support storing unboxed `T`s by-value. Retain existing invariant transformations which make sense in the context of values (e.g., transformations on bit validity).
## Motivation
Many of the behaviors of `Ptr` aren't actually specific to pointers. For example, a hypothetical `MaybeValue` could keep track of whether it owns a bit-valid `T` just as `Ptr` does, and could provide various invariant state transitions.
Instead of introducing a new `MaybeValue` type, we could just teach `Ptr` to also store values. This would permit us to re-use existing `Ptr` conversions which are not specific to pointers and apply those conversions to values.
This would also permit us to replace or unify some existing abstractions:
- `Unalign` and [`UnalignUnsized`](https://github.com/google/zerocopy/pull/1828)
- [`MaybeUninit`](https://github.com/google/zerocopy/issues/1797)
- [`ReadOnly`](https://github.com/google/zerocopy/issues/1760)
It would also dovetail nicely with [extending `Ptr` to support other pointer types](https://github.com/google/zerocopy/issues/1183).
## Design
Building on #1797, we can make this support `T: ?Sized + KnownLayout` like so:
```rust
struct Ptr<'a, T, I>
where
T: ?Sized,
I: Invariants,
I::Aliasing: Aliasing<'a, T>
{
inner: >::Inner,
}
trait Invariants {
type Aliasing;
}
trait Aliasing<'a, T: ?Sized> {
type Inner;
}
enum Value {}
impl<'a, T: ?Sized + KnownLayout> Aliasing<'a, T> for Value {
type Inner = T::MaybeUninit; // New associated type on `KnownLayout`; see #1797, #1822
}
enum Shared {}
impl<'a, T: ?Sized + KnownLayout> Aliasing<'a, T> for Shared {
type Inner = NonNull;
}
enum Exclusive {}
impl<'a, T: ?Sized + KnownLayout> Aliasing<'a, T> for Exclusive {
type Inner = NonNull;
}
```
This design is prototyped [here](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=c17d6f9f6e3d6ddf74545c71e072eab9), although it looks slightly different since we have to redefine various zerocopy internals to get it to work on the Rust playground.
This dovetails with #1839, which may require us to store something other than a `NonNull` for `Exclusive`-aliased `Ptr`s.
### Open questions
- How do we support `Drop`? If we're supporting boxed (`Box`) or unboxed (`T`) values, we need to support `Drop`, but only when certain invariants (e.g., bit validity) are satisfied.
Contributor guide
Assessment
This issue has not been assessed yet.