1010
1111//! The parameterized invariants of a [`Ptr`][super::Ptr].
1212//!
13- //! Invariants are encoded as ([`Aliasing`], [`Alignment`], [`Validity`])
14- //! triples implementing the [`Invariants`] trait.
13+ //! A `Ptr<V, I>` has the following invariants:
14+ //! - [`V: Validity`][validity-trait] encodes the bit validity of `Ptr`'s
15+ //! referent, which is of type [`V::Inner`][validity-inner]
16+ //! - [`I: Invariants`][invariants-trait], where
17+ //! [`I::Aliasing`][invariants-aliasing] and
18+ //! [`I::Alignment`][invariants-alignment] encode the `Ptr`'s aliasing and
19+ //! alignment invariants respectively
20+ //!
21+ //! [validity-trait]: Validity
22+ //! [validity-inner]: Validity::Inner
23+ //! [invariants-trait]: Invariants
24+ //! [invariants-aliasing]: Invariants::Aliasing
25+ //! [invariants-alignment]: Invariants::Alignment
26+
27+ use core:: marker:: PhantomData ;
1528
16- /// The invariants of a [`Ptr`][super::Ptr].
29+ /// The aliasing and alignment invariants of a [`Ptr`][super::Ptr].
1730pub trait Invariants : Sealed {
1831 type Aliasing : Aliasing ;
1932 type Alignment : Alignment ;
20- type Validity : Validity ;
2133
2234 /// Invariants identical to `Self` except with a different aliasing
2335 /// invariant.
24- type WithAliasing < A : Aliasing > : Invariants <
25- Aliasing = A ,
26- Alignment = Self :: Alignment ,
27- Validity = Self :: Validity ,
28- > ;
36+ type WithAliasing < A : Aliasing > : Invariants < Aliasing = A , Alignment = Self :: Alignment > ;
2937
3038 /// Invariants identical to `Self` except with a different alignment
3139 /// invariant.
32- type WithAlignment < A : Alignment > : Invariants <
33- Aliasing = Self :: Aliasing ,
34- Alignment = A ,
35- Validity = Self :: Validity ,
36- > ;
37-
38- /// Invariants identical to `Self` except with a different validity
39- /// invariant.
40- type WithValidity < V : Validity > : Invariants <
41- Aliasing = Self :: Aliasing ,
42- Alignment = Self :: Alignment ,
43- Validity = V ,
44- > ;
40+ type WithAlignment < A : Alignment > : Invariants < Aliasing = Self :: Aliasing , Alignment = A > ;
4541}
4642
47- impl < A : Aliasing , AA : Alignment , V : Validity > Invariants for ( A , AA , V ) {
43+ impl < A : Aliasing , AA : Alignment > Invariants for ( A , AA ) {
4844 type Aliasing = A ;
4945 type Alignment = AA ;
50- type Validity = V ;
5146
52- type WithAliasing < AB : Aliasing > = ( AB , AA , V ) ;
53- type WithAlignment < AB : Alignment > = ( A , AB , V ) ;
54- type WithValidity < VB : Validity > = ( A , AA , VB ) ;
47+ type WithAliasing < AB : Aliasing > = ( AB , AA ) ;
48+ type WithAlignment < AB : Alignment > = ( A , AB ) ;
5549}
5650
5751/// The aliasing invariant of a [`Ptr`][super::Ptr].
@@ -79,7 +73,24 @@ pub trait Alignment: Sealed {
7973}
8074
8175/// The validity invariant of a [`Ptr`][super::Ptr].
76+ ///
77+ /// A `V: Validity` defines both the referent type of a `Ptr<V>`
78+ /// ([`V::Inner`](Validity::Inner)) and the bit validity of the referent value.
79+ /// Bit validity specifies a set, `S`, of possible values which may exist at the
80+ /// `Ptr`'s referent. Code operating on a `Ptr` may assume that bit validity
81+ /// holds - namely, that it will only observe referent values in `S`. It must
82+ /// also uphold bit validity - namely, it must only write values in `S` to the
83+ /// referent.
84+ ///
85+ /// The specific definition of `S` for a given validity type (i.e., `V:
86+ /// Validity`) is documented on that type.
87+ ///
88+ /// The available validities are [`Uninit`], [`AsInitialized`], [`Initialized`],
89+ /// and [`Valid`].
8290pub trait Validity : Sealed {
91+ type Inner : ?Sized ;
92+ type WithInner < T : ?Sized > : Validity < Inner = T > ;
93+
8394 #[ doc( hidden) ]
8495 type MappedTo < M : ValidityMapping > : Validity ;
8596}
@@ -98,8 +109,16 @@ pub enum Unknown {}
98109impl Alignment for Unknown {
99110 type MappedTo < M : AlignmentMapping > = M :: FromUnknown ;
100111}
101- impl Validity for Unknown {
102- type MappedTo < M : ValidityMapping > = M :: FromUnknown ;
112+
113+ /// A validity which permits arbitrary bytes - including uninitialized bytes -
114+ /// at any byte offset.
115+ pub struct Uninit < T : ?Sized = ( ) > ( PhantomData < T > ) ;
116+
117+ impl < T : ?Sized > Validity for Uninit < T > {
118+ type Inner = T ;
119+ type WithInner < U : ?Sized > = Uninit < U > ;
120+
121+ type MappedTo < M : ValidityMapping > = M :: FromUninit < T > ;
103122}
104123
105124/// The `Ptr<'a, T>` adheres to the aliasing rules of a `&'a T`.
@@ -138,11 +157,11 @@ impl Alignment for Aligned {
138157
139158/// The byte ranges initialized in `T` are also initialized in the referent.
140159///
141- /// Formally: uninitialized bytes may only be present in `Ptr<T>`'s referent
142- /// where they are guaranteed to be present in `T`. This is a dynamic property:
143- /// if, at a particular byte offset, a valid enum discriminant is set, the
144- /// subsequent bytes may only have uninitialized bytes as specificed by the
145- /// corresponding enum.
160+ /// Formally: uninitialized bytes may only be present in
161+ /// `Ptr<AsInitialized<T>>`'s referent where they are guaranteed to be present
162+ /// in `T`. This is a dynamic property: if, at a particular byte offset, a valid
163+ /// enum discriminant is set, the subsequent bytes may only have uninitialized
164+ /// bytes as specificed by the corresponding enum.
146165///
147166/// Formally, given `len = size_of_val_raw(ptr)`, at every byte offset, `b`, in
148167/// the range `[0, len)`:
@@ -162,22 +181,28 @@ impl Alignment for Aligned {
162181/// variant's bit validity (although note that the variant may contain another
163182/// enum type, in which case the same rules apply depending on the state of
164183/// its discriminant, and so on recursively).
165- pub enum AsInitialized { }
166- impl Validity for AsInitialized {
167- type MappedTo < M : ValidityMapping > = M :: FromAsInitialized ;
184+ pub struct AsInitialized < T : ?Sized = ( ) > ( PhantomData < T > ) ;
185+ impl < T : ?Sized > Validity for AsInitialized < T > {
186+ type Inner = T ;
187+ type WithInner < U : ?Sized > = AsInitialized < U > ;
188+ type MappedTo < M : ValidityMapping > = M :: FromAsInitialized < T > ;
168189}
169190
170191/// The byte ranges in the referent are fully initialized. In other words, if
171192/// the referent is `N` bytes long, then it contains a bit-valid `[u8; N]`.
172- pub enum Initialized { }
173- impl Validity for Initialized {
174- type MappedTo < M : ValidityMapping > = M :: FromInitialized ;
193+ pub struct Initialized < T : ?Sized = ( ) > ( PhantomData < T > ) ;
194+ impl < T : ?Sized > Validity for Initialized < T > {
195+ type Inner = T ;
196+ type WithInner < U : ?Sized > = Initialized < U > ;
197+ type MappedTo < M : ValidityMapping > = M :: FromInitialized < T > ;
175198}
176199
177200/// The referent is bit-valid for `T`.
178- pub enum Valid { }
179- impl Validity for Valid {
180- type MappedTo < M : ValidityMapping > = M :: FromValid ;
201+ pub struct Valid < T : ?Sized = ( ) > ( PhantomData < T > ) ;
202+ impl < T : ?Sized > Validity for Valid < T > {
203+ type Inner = T ;
204+ type WithInner < U : ?Sized > = Valid < U > ;
205+ type MappedTo < M : ValidityMapping > = M :: FromValid < T > ;
181206}
182207
183208/// [`Ptr`](crate::Ptr) referents that permit unsynchronized read operations.
@@ -224,16 +249,18 @@ mod sealed {
224249
225250 impl Sealed for Unknown { }
226251
252+ impl < T : ?Sized > Sealed for Uninit < T > { }
253+
227254 impl Sealed for Shared { }
228255 impl Sealed for Exclusive { }
229256
230257 impl Sealed for Aligned { }
231258
232- impl Sealed for AsInitialized { }
233- impl Sealed for Initialized { }
234- impl Sealed for Valid { }
259+ impl < T : ? Sized > Sealed for AsInitialized < T > { }
260+ impl < T : ? Sized > Sealed for Initialized < T > { }
261+ impl < T : ? Sized > Sealed for Valid < T > { }
235262
236- impl < A : Sealed , AA : Sealed , V : Sealed > Sealed for ( A , AA , V ) { }
263+ impl < A : Sealed , AA : Sealed > Sealed for ( A , AA ) { }
237264}
238265
239266pub use mapping:: * ;
@@ -268,10 +295,10 @@ mod mapping {
268295 /// Mappings are used by [`Ptr`](crate::Ptr) conversion methods to preserve
269296 /// or modify invariants as required by each method's semantics.
270297 pub trait ValidityMapping {
271- type FromUnknown : Validity ;
272- type FromAsInitialized : Validity ;
273- type FromInitialized : Validity ;
274- type FromValid : Validity ;
298+ type FromUninit < T : ? Sized > : Validity ;
299+ type FromAsInitialized < T : ? Sized > : Validity ;
300+ type FromInitialized < T : ? Sized > : Validity ;
301+ type FromValid < T : ? Sized > : Validity ;
275302 }
276303
277304 /// The application of the [`AlignmentMapping`] `M` to the [`Alignment`] `A`.
@@ -280,7 +307,8 @@ mod mapping {
280307
281308 /// The application of the [`ValidityMapping`] `M` to the [`Validity`] `A`.
282309 #[ allow( type_alias_bounds) ]
283- pub type MappedValidity < V : Validity , M : ValidityMapping > = V :: MappedTo < M > ;
310+ pub type MappedValidity < V : Validity , U : ?Sized , M : ValidityMapping > =
311+ <V :: MappedTo < M > as Validity >:: WithInner < U > ;
284312
285313 impl < FromUnknown : Alignment , FromAligned : Alignment > AlignmentMapping
286314 for ( ( Unknown , FromUnknown ) , ( Shared , FromAligned ) )
@@ -290,28 +318,28 @@ mod mapping {
290318 }
291319
292320 impl <
293- FromUnknown : Validity ,
321+ FromUninit : Validity ,
294322 FromAsInitialized : Validity ,
295323 FromInitialized : Validity ,
296324 FromValid : Validity ,
297325 > ValidityMapping
298326 for (
299- ( Unknown , FromUnknown ) ,
327+ ( Unknown , FromUninit ) ,
300328 ( AsInitialized , FromAsInitialized ) ,
301329 ( Initialized , FromInitialized ) ,
302330 ( Valid , FromValid ) ,
303331 )
304332 {
305- type FromUnknown = FromUnknown ;
306- type FromAsInitialized = FromAsInitialized ;
307- type FromInitialized = FromInitialized ;
308- type FromValid = FromValid ;
333+ type FromUninit < T : ? Sized > = FromUninit :: WithInner < T > ;
334+ type FromAsInitialized < T : ? Sized > = FromAsInitialized :: WithInner < T > ;
335+ type FromInitialized < T : ? Sized > = FromInitialized :: WithInner < T > ;
336+ type FromValid < T : ? Sized > = FromValid :: WithInner < T > ;
309337 }
310338
311339 impl < FromInitialized : Validity > ValidityMapping for ( Initialized , FromInitialized ) {
312- type FromUnknown = Unknown ;
313- type FromAsInitialized = Unknown ;
314- type FromInitialized = FromInitialized ;
315- type FromValid = Unknown ;
340+ type FromUninit < T : ? Sized > = Uninit < T > ;
341+ type FromAsInitialized < T : ? Sized > = Uninit < T > ;
342+ type FromInitialized < T : ? Sized > = FromInitialized :: WithInner < T > ;
343+ type FromValid < T : ? Sized > = Uninit < T > ;
316344 }
317345}
0 commit comments