my apologies. after some pondering, I think my statement was wrong, a better wording would be, "MaybeUninit
solves problems that are orthogonal to provenances".
MaybeUninit
, as its name suggests, deals with uninitialized memory. it's UB to read uninitialized values, or to create references to them, unless the value has the type MaybeUninit<T>
. here T
can be any type, this includes, but is not specific to, pointer types.
provenances are just some information of pointers (in addition to "memory addresses"). when reasoning about provenances, we must have valid pointers to begin with. uninitialized pointers are not valid pointers, obviously.
in the linked post, MaybeUninit
is mentioned when they talk about transmutations, where MaybeUninit
is "the right type to hold arbitrary data", to avoid "under-specified layout" related UB. and naturally, "arbitrary data" includes pointer types, and it happens that the exact layout of pointer types (consisting of provenances and addresses, and also metadata if we talk about "fat" pointers) is unspecified.
so, using slice of u8
as the output parameter to store untyped ("arbitrary") data would be indeed incorrect, however, using Vec<u8>
is not UB immediately but still unsound. instead, we can either use Vec
(or slice) of MaybeUninit<u8>
, or we can
use raw pointers NonNull<u8>
.
note this is the same situation of transmutation: type punning through memory behaves "as-if" it was transmuted, it is not specific to provenance per se, but it apply to pointers, thus the associated provenances.