google / google/zerocopy

Extend `Ptr` to store unboxed values

Open
#1,875 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

## 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

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.