There’ve been a few extra built-in pointer types proposed, but I’ve not yet seen a single place for discussion about them. In particular, I’m thinking about the &move
and &uninit
(or &out
) hypothetical pointer types. I would recommend reading this RFC on uninitialised pointers for information about &uninit
if you haven’t already read it, and this GitHub comment thread discusses owning and uninitialised pointers (and is the earliest reference to them I can find).
One can classify these hypothetical types and the existing pointer types into a system that gives every pointer a set of properties which represent what one can do with the pointer, and what the restrictions on creating it are: uniqueness (which gives mutability), uninitialisedness (which requires moving in, and implies uniqueness), and ownership (which allows moving out, and also implies uniqueness). (I’ve considered making mutability separate from uniqueness, but it causes too many problems to be worth bothering with.) With this in mind, we have five pointer types: &
, an immutable, shared pointer; &mut
, a mutable, unique pointer; &move
, a mutable, unique, owning pointer; and uninitialised variants of the latter two pointer types (called &uninit
and &uninit move
), which would be created by moving out of the corresponding initialised versions.
A key thing to realise here is that under this scheme, &move
and &mut
actually allow the same operations (mutating, moving out). The only difference is the type created when they are moved out of. &mut
can still be moved out of, creating a &uninit
, which has to be filled in again before the end of the scope. &move
can be moved out of, but it creates an &uninit move
, which does not have to be filled in before it dies. This (&uninit move
) is where &move
gets its real advantage from. (I still have no idea what &uninit move
would actually be used for, though—maybe the original system with four types is easier.)
I’ve rambled enough; time to get down to the real reason why I created this issue: as a place to put the discussion about &move
and &uninit
(and maybe any other reference types). What are some good uses of these types? I can think of a few: implementing DerefMove<[T]>
on Vec
(where DerefMove
provides &move
equivalents of Deref
), and changing FnOnce
to use &move self
to make trait objects make more sense. &uninit
is potentially useful for a safe ‘placement box
’ API. But does anyone else have any more motivation for these types, perhaps even enough for a concrete proposal some time after 1.0 to make sense?