Skip to content

Extend Ptr to store unboxed values #1875

Open
@joshlf

Description

@joshlf

Overview

Extend Ptr to support storing unboxed Ts 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 Ptrs.

Open questions

  • How do we support Drop? If we're supporting boxed (Box<T>) or unboxed (T) values, we need to support Drop, but only when certain invariants (e.g., bit validity) are satisfied.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions