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<T>
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:
It would also dovetail nicely with extending Ptr
to support other pointer types.
Design
Building on #1797, we can make this support T: ?Sized + KnownLayout
like so:
struct Ptr<'a, T, I>
where
T: ?Sized,
I: Invariants,
I::Aliasing: Aliasing<'a, T>
{
inner: <I::Aliasing as Aliasing<'a, T>>::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<T>;
}
enum Exclusive {}
impl<'a, T: ?Sized + KnownLayout> Aliasing<'a, T> for Exclusive {
type Inner = NonNull<T>;
}
This design is prototyped here, 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<T>
for Exclusive
-aliased Ptr
s.
Open questions
- How do we support
Drop
? If we're supporting boxed (Box<T>
) or unboxed (T
) values, we need to supportDrop
, but only when certain invariants (e.g., bit validity) are satisfied.