You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
In #2334, inspired by #1866 (comment), we moved the validity invariant of Ptrs into the type position. This move was inspired by the observation that the "set of possible valid referents" has a name in type theory — i.e., a type. However, technical limitations prevented us from wholly integrating validity as "real" type. In particular:
Initialized<T> is not expressible, because initialized bytes written to padding locations in MaybeUninit<T> are almost certainly not preserved through typed copy.
We could perhaps work around this by requiring KnownLayout and repr(C) recursively on all fields, but this requirement seems onerous. We probably need language support for this case.
#2334 works around this by introducing 'virtual' wrapper types — Uninit<T>, Initialized<T>, AsInitialized<T>, and Valid<T> — that occupy the type position of Ptr but which are not, themselves, real, instantiated types. This trick lets us revise Ptr's API in such a way that makes it less likely for us to independently and invalidly update T and the validity (see #1866).
Now, as we begin to extend Ptr to support owned Box, Arc and the ilk (#1183), we have discovered a modeling challenge between the aliasing mode and alignment. We are considering modeling Box, Arc, etc., as distinct aliasing modes, but it is unsound for such pointers to be unaligned or to change alignment. This leads to some modeling challenges:
For example, while going from a Ptr<_, [u8; 2], (Aligned, Exclusive)> to Ptr<_, u16, (Unaligned, Exclusive)> is sound, going from a Ptr<_, [u8; 2], (Aligned, Box)> to Ptr<_, u16, (Unaligned, Box)> is not, or at least unusable — it is unsound to even drop the resulting Ptr.
For example, while going from a Ptr<_, u16, (Aligned, Exclusive)> to Ptr<_, [u8; 2], (Aligned, Exclusive)> to &mut [u8; 2] is sound, going from a Ptr<_, u16, (Aligned, Box)> to Ptr<_, [u8; 2], (Aligned, Box)> to Box<[u8; 2]> is not — again, it would be unsound to drop the resulting Box.
Once again, we must tread carefully before transitioning between the referent type and an invariant (in this case, alignment). Whereas it was impossible to really move the validity into the type position in #2334, that is not the case for alignment: #1828 provides a prototype implementation of UnalignUnsized. Taking this approach would require us to require KnownLayout on Ptr's referent, but that might have minimal impact on our public API — only affecting APIs which operate on unsized types that do not already have a KnownLayout bound. This is a small list, encompassing FromZeros::zero and possibly nothing else.
The text was updated successfully, but these errors were encountered:
In #2334, inspired by #1866 (comment), we moved the validity invariant of
Ptr
s into the type position. This move was inspired by the observation that the "set of possible valid referents" has a name in type theory — i.e., a type. However, technical limitations prevented us from wholly integrating validity as "real" type. In particular:MaybeUninit<T>
requiresT: Sized
AsInitialized<T>
is possibly not expressible because initialized bytes which are written to initialized-but-invalid positions inMaybeUninit<T>
are not necessarily preserved through a typed copy (Do typed copies of unions preserve "invalid" bytes? rust-lang/unsafe-code-guidelines#555)Initialized<T>
is not expressible, because initialized bytes written to padding locations inMaybeUninit<T>
are almost certainly not preserved through typed copy.KnownLayout
andrepr(C)
recursively on all fields, but this requirement seems onerous. We probably need language support for this case.#2334 works around this by introducing 'virtual' wrapper types —
Uninit<T>
,Initialized<T>
,AsInitialized<T>
, andValid<T>
— that occupy the type position ofPtr
but which are not, themselves, real, instantiated types. This trick lets us revisePtr
's API in such a way that makes it less likely for us to independently and invalidly updateT
and the validity (see #1866).Now, as we begin to extend
Ptr
to support ownedBox
,Arc
and the ilk (#1183), we have discovered a modeling challenge between the aliasing mode and alignment. We are considering modelingBox
,Arc
, etc., as distinct aliasing modes, but it is unsound for such pointers to be unaligned or to change alignment. This leads to some modeling challenges:Ptr<_, [u8; 2], (Aligned, Exclusive)>
toPtr<_, u16, (Unaligned, Exclusive)>
is sound, going from aPtr<_, [u8; 2], (Aligned, Box)>
toPtr<_, u16, (Unaligned, Box)>
is not, or at least unusable — it is unsound to even drop the resultingPtr
.Ptr<_, u16, (Aligned, Exclusive)>
toPtr<_, [u8; 2], (Aligned, Exclusive)>
to&mut [u8; 2]
is sound, going from aPtr<_, u16, (Aligned, Box)>
toPtr<_, [u8; 2], (Aligned, Box)>
toBox<[u8; 2]>
is not — again, it would be unsound to drop the resultingBox
.Once again, we must tread carefully before transitioning between the referent type and an invariant (in this case, alignment). Whereas it was impossible to really move the validity into the type position in #2334, that is not the case for alignment: #1828 provides a prototype implementation of
UnalignUnsized
. Taking this approach would require us to requireKnownLayout
onPtr
's referent, but that might have minimal impact on our public API — only affecting APIs which operate on unsized types that do not already have aKnownLayout
bound. This is a small list, encompassingFromZeros::zero
and possibly nothing else.The text was updated successfully, but these errors were encountered: