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,16 @@ 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
+ 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 > ;
103
122
}
104
123
105
124
/// The `Ptr<'a, T>` adheres to the aliasing rules of a `&'a T`.
@@ -138,11 +157,11 @@ impl Alignment for Aligned {
138
157
139
158
/// The byte ranges initialized in `T` are also initialized in the referent.
140
159
///
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.
146
165
///
147
166
/// Formally, given `len = size_of_val_raw(ptr)`, at every byte offset, `b`, in
148
167
/// the range `[0, len)`:
@@ -162,22 +181,28 @@ impl Alignment for Aligned {
162
181
/// variant's bit validity (although note that the variant may contain another
163
182
/// enum type, in which case the same rules apply depending on the state of
164
183
/// 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 > ;
168
189
}
169
190
170
191
/// The byte ranges in the referent are fully initialized. In other words, if
171
192
/// 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 > ;
175
198
}
176
199
177
200
/// 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 > ;
181
206
}
182
207
183
208
/// [`Ptr`](crate::Ptr) referents that permit unsynchronized read operations.
@@ -224,16 +249,18 @@ mod sealed {
224
249
225
250
impl Sealed for Unknown { }
226
251
252
+ impl < T : ?Sized > Sealed for Uninit < T > { }
253
+
227
254
impl Sealed for Shared { }
228
255
impl Sealed for Exclusive { }
229
256
230
257
impl Sealed for Aligned { }
231
258
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 > { }
235
262
236
- impl < A : Sealed , AA : Sealed , V : Sealed > Sealed for ( A , AA , V ) { }
263
+ impl < A : Sealed , AA : Sealed > Sealed for ( A , AA ) { }
237
264
}
238
265
239
266
pub use mapping:: * ;
@@ -268,10 +295,10 @@ mod mapping {
268
295
/// Mappings are used by [`Ptr`](crate::Ptr) conversion methods to preserve
269
296
/// or modify invariants as required by each method's semantics.
270
297
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 ;
275
302
}
276
303
277
304
/// The application of the [`AlignmentMapping`] `M` to the [`Alignment`] `A`.
@@ -280,7 +307,8 @@ mod mapping {
280
307
281
308
/// The application of the [`ValidityMapping`] `M` to the [`Validity`] `A`.
282
309
#[ 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 > ;
284
312
285
313
impl < FromUnknown : Alignment , FromAligned : Alignment > AlignmentMapping
286
314
for ( ( Unknown , FromUnknown ) , ( Shared , FromAligned ) )
@@ -290,28 +318,28 @@ mod mapping {
290
318
}
291
319
292
320
impl <
293
- FromUnknown : Validity ,
321
+ FromUninit : Validity ,
294
322
FromAsInitialized : Validity ,
295
323
FromInitialized : Validity ,
296
324
FromValid : Validity ,
297
325
> ValidityMapping
298
326
for (
299
- ( Unknown , FromUnknown ) ,
327
+ ( Unknown , FromUninit ) ,
300
328
( AsInitialized , FromAsInitialized ) ,
301
329
( Initialized , FromInitialized ) ,
302
330
( Valid , FromValid ) ,
303
331
)
304
332
{
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 > ;
309
337
}
310
338
311
339
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 > ;
316
344
}
317
345
}
0 commit comments