10
10
11
11
//! The parameterized invariants of a [`Ptr`][super::Ptr].
12
12
//!
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 ;
15
28
16
- /// The invariants of a [`Ptr`][super::Ptr].
29
+ /// The aliasing and alignment invariants of a [`Ptr`][super::Ptr].
17
30
pub trait Invariants : Sealed {
18
31
type Aliasing : Aliasing ;
19
32
type Alignment : Alignment ;
20
- type Validity : Validity ;
21
33
22
34
/// Invariants identical to `Self` except with a different aliasing
23
35
/// 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 > ;
29
37
30
38
/// Invariants identical to `Self` except with a different alignment
31
39
/// 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 > ;
45
41
}
46
42
47
- impl < A : Aliasing , AA : Alignment , V : Validity > Invariants for ( A , AA , V ) {
43
+ impl < A : Aliasing , AA : Alignment > Invariants for ( A , AA ) {
48
44
type Aliasing = A ;
49
45
type Alignment = AA ;
50
- type Validity = V ;
51
46
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 ) ;
55
49
}
56
50
57
51
/// The aliasing invariant of a [`Ptr`][super::Ptr].
@@ -79,7 +73,24 @@ pub trait Alignment: Sealed {
79
73
}
80
74
81
75
/// 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`].
82
90
pub trait Validity : Sealed {
91
+ type Inner : ?Sized ;
92
+ type WithInner < T : ?Sized > : Validity < Inner = T > ;
93
+
83
94
#[ doc( hidden) ]
84
95
type MappedTo < M : ValidityMapping > : Validity ;
85
96
}
@@ -98,8 +109,19 @@ pub enum Unknown {}
98
109
impl Alignment for Unknown {
99
110
type MappedTo < M : AlignmentMapping > = M :: FromUnknown ;
100
111
}
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
+ ///
116
+ /// The referent of a `Ptr<Uninit<T>>` may contain arbitrary bytes - including
117
+ /// uninitialized bytes - at any byte offset.
118
+ pub struct Uninit < T : ?Sized = ( ) > ( PhantomData < T > ) ;
119
+
120
+ impl < T : ?Sized > Validity for Uninit < T > {
121
+ type Inner = T ;
122
+ type WithInner < U : ?Sized > = Uninit < U > ;
123
+
124
+ type MappedTo < M : ValidityMapping > = M :: FromUninit < T > ;
103
125
}
104
126
105
127
/// The `Ptr<'a, T>` adheres to the aliasing rules of a `&'a T`.
@@ -138,11 +160,11 @@ impl Alignment for Aligned {
138
160
139
161
/// The byte ranges initialized in `T` are also initialized in the referent.
140
162
///
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.
163
+ /// Formally: uninitialized bytes may only be present in
164
+ /// `Ptr<AsInitialized<T>>`'s referent where they are guaranteed to be present
165
+ /// in `T`. This is a dynamic property: if, at a particular byte offset, a valid
166
+ /// enum discriminant is set, the subsequent bytes may only have uninitialized
167
+ /// bytes as specificed by the corresponding enum.
146
168
///
147
169
/// Formally, given `len = size_of_val_raw(ptr)`, at every byte offset, `b`, in
148
170
/// the range `[0, len)`:
@@ -162,22 +184,28 @@ impl Alignment for Aligned {
162
184
/// variant's bit validity (although note that the variant may contain another
163
185
/// enum type, in which case the same rules apply depending on the state of
164
186
/// its discriminant, and so on recursively).
165
- pub enum AsInitialized { }
166
- impl Validity for AsInitialized {
167
- type MappedTo < M : ValidityMapping > = M :: FromAsInitialized ;
187
+ pub struct AsInitialized < T : ?Sized = ( ) > ( PhantomData < T > ) ;
188
+ impl < T : ?Sized > Validity for AsInitialized < T > {
189
+ type Inner = T ;
190
+ type WithInner < U : ?Sized > = AsInitialized < U > ;
191
+ type MappedTo < M : ValidityMapping > = M :: FromAsInitialized < T > ;
168
192
}
169
193
170
194
/// The byte ranges in the referent are fully initialized. In other words, if
171
195
/// 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 ;
196
+ pub struct Initialized < T : ?Sized = ( ) > ( PhantomData < T > ) ;
197
+ impl < T : ?Sized > Validity for Initialized < T > {
198
+ type Inner = T ;
199
+ type WithInner < U : ?Sized > = Initialized < U > ;
200
+ type MappedTo < M : ValidityMapping > = M :: FromInitialized < T > ;
175
201
}
176
202
177
203
/// The referent is bit-valid for `T`.
178
- pub enum Valid { }
179
- impl Validity for Valid {
180
- type MappedTo < M : ValidityMapping > = M :: FromValid ;
204
+ pub struct Valid < T : ?Sized = ( ) > ( PhantomData < T > ) ;
205
+ impl < T : ?Sized > Validity for Valid < T > {
206
+ type Inner = T ;
207
+ type WithInner < U : ?Sized > = Valid < U > ;
208
+ type MappedTo < M : ValidityMapping > = M :: FromValid < T > ;
181
209
}
182
210
183
211
/// [`Ptr`](crate::Ptr) referents that permit unsynchronized read operations.
@@ -224,16 +252,18 @@ mod sealed {
224
252
225
253
impl Sealed for Unknown { }
226
254
255
+ impl < T : ?Sized > Sealed for Uninit < T > { }
256
+
227
257
impl Sealed for Shared { }
228
258
impl Sealed for Exclusive { }
229
259
230
260
impl Sealed for Aligned { }
231
261
232
- impl Sealed for AsInitialized { }
233
- impl Sealed for Initialized { }
234
- impl Sealed for Valid { }
262
+ impl < T : ? Sized > Sealed for AsInitialized < T > { }
263
+ impl < T : ? Sized > Sealed for Initialized < T > { }
264
+ impl < T : ? Sized > Sealed for Valid < T > { }
235
265
236
- impl < A : Sealed , AA : Sealed , V : Sealed > Sealed for ( A , AA , V ) { }
266
+ impl < A : Sealed , AA : Sealed > Sealed for ( A , AA ) { }
237
267
}
238
268
239
269
pub use mapping:: * ;
@@ -268,10 +298,10 @@ mod mapping {
268
298
/// Mappings are used by [`Ptr`](crate::Ptr) conversion methods to preserve
269
299
/// or modify invariants as required by each method's semantics.
270
300
pub trait ValidityMapping {
271
- type FromUnknown : Validity ;
272
- type FromAsInitialized : Validity ;
273
- type FromInitialized : Validity ;
274
- type FromValid : Validity ;
301
+ type FromUninit < T : ? Sized > : Validity ;
302
+ type FromAsInitialized < T : ? Sized > : Validity ;
303
+ type FromInitialized < T : ? Sized > : Validity ;
304
+ type FromValid < T : ? Sized > : Validity ;
275
305
}
276
306
277
307
/// The application of the [`AlignmentMapping`] `M` to the [`Alignment`] `A`.
@@ -280,7 +310,8 @@ mod mapping {
280
310
281
311
/// The application of the [`ValidityMapping`] `M` to the [`Validity`] `A`.
282
312
#[ allow( type_alias_bounds) ]
283
- pub type MappedValidity < V : Validity , M : ValidityMapping > = V :: MappedTo < M > ;
313
+ pub type MappedValidity < V : Validity , U : ?Sized , M : ValidityMapping > =
314
+ <V :: MappedTo < M > as Validity >:: WithInner < U > ;
284
315
285
316
impl < FromUnknown : Alignment , FromAligned : Alignment > AlignmentMapping
286
317
for ( ( Unknown , FromUnknown ) , ( Shared , FromAligned ) )
@@ -290,28 +321,28 @@ mod mapping {
290
321
}
291
322
292
323
impl <
293
- FromUnknown : Validity ,
324
+ FromUninit : Validity ,
294
325
FromAsInitialized : Validity ,
295
326
FromInitialized : Validity ,
296
327
FromValid : Validity ,
297
328
> ValidityMapping
298
329
for (
299
- ( Unknown , FromUnknown ) ,
330
+ ( Unknown , FromUninit ) ,
300
331
( AsInitialized , FromAsInitialized ) ,
301
332
( Initialized , FromInitialized ) ,
302
333
( Valid , FromValid ) ,
303
334
)
304
335
{
305
- type FromUnknown = FromUnknown ;
306
- type FromAsInitialized = FromAsInitialized ;
307
- type FromInitialized = FromInitialized ;
308
- type FromValid = FromValid ;
336
+ type FromUninit < T : ? Sized > = FromUninit :: WithInner < T > ;
337
+ type FromAsInitialized < T : ? Sized > = FromAsInitialized :: WithInner < T > ;
338
+ type FromInitialized < T : ? Sized > = FromInitialized :: WithInner < T > ;
339
+ type FromValid < T : ? Sized > = FromValid :: WithInner < T > ;
309
340
}
310
341
311
342
impl < FromInitialized : Validity > ValidityMapping for ( Initialized , FromInitialized ) {
312
- type FromUnknown = Unknown ;
313
- type FromAsInitialized = Unknown ;
314
- type FromInitialized = FromInitialized ;
315
- type FromValid = Unknown ;
343
+ type FromUninit < T : ? Sized > = Uninit < T > ;
344
+ type FromAsInitialized < T : ? Sized > = Uninit < T > ;
345
+ type FromInitialized < T : ? Sized > = FromInitialized :: WithInner < T > ;
346
+ type FromValid < T : ? Sized > = Uninit < T > ;
316
347
}
317
348
}
0 commit comments