@@ -65,13 +65,22 @@ pub trait Aliasing: Sealed {
6565 /// Aliasing>::Variance<'a, T>` to inherit this variance.
6666 #[ doc( hidden) ]
6767 type Variance < ' a , T : ' a + ?Sized > ;
68+
69+ #[ doc( hidden) ]
70+ type MappedTo < M : AliasingMapping > : Aliasing ;
6871}
6972
7073/// The alignment invariant of a [`Ptr`][super::Ptr].
71- pub trait Alignment : Sealed { }
74+ pub trait Alignment : Sealed {
75+ #[ doc( hidden) ]
76+ type MappedTo < M : AlignmentMapping > : Alignment ;
77+ }
7278
7379/// The validity invariant of a [`Ptr`][super::Ptr].
74- pub trait Validity : Sealed { }
80+ pub trait Validity : Sealed {
81+ #[ doc( hidden) ]
82+ type MappedTo < M : ValidityMapping > : Validity ;
83+ }
7584
7685/// An [`Aliasing`] invariant which is either [`Shared`] or [`Exclusive`].
7786///
@@ -84,8 +93,12 @@ pub trait Reference: Aliasing + Sealed {}
8493/// It is unknown whether any invariant holds.
8594pub enum Unknown { }
8695
87- impl Alignment for Unknown { }
88- impl Validity for Unknown { }
96+ impl Alignment for Unknown {
97+ type MappedTo < M : AlignmentMapping > = M :: FromUnknown ;
98+ }
99+ impl Validity for Unknown {
100+ type MappedTo < M : ValidityMapping > = M :: FromUnknown ;
101+ }
89102
90103/// The `Ptr<'a, T>` adheres to the aliasing rules of a `&'a T`.
91104///
@@ -99,6 +112,7 @@ pub enum Shared {}
99112impl Aliasing for Shared {
100113 const IS_EXCLUSIVE : bool = false ;
101114 type Variance < ' a , T : ' a + ?Sized > = & ' a T ;
115+ type MappedTo < M : AliasingMapping > = M :: FromShared ;
102116}
103117impl Reference for Shared { }
104118
@@ -111,51 +125,60 @@ pub enum Exclusive {}
111125impl Aliasing for Exclusive {
112126 const IS_EXCLUSIVE : bool = true ;
113127 type Variance < ' a , T : ' a + ?Sized > = & ' a mut T ;
128+ type MappedTo < M : AliasingMapping > = M :: FromExclusive ;
114129}
115130impl Reference for Exclusive { }
116131
117- /// The referent is aligned: for `Ptr<T>`, the referent's address is a multiple
118- /// of the `T`'s alignment.
132+ /// The referent is aligned: for `Ptr<T>`, the referent's address is a
133+ /// multiple of the `T`'s alignment.
119134pub enum Aligned { }
120- impl Alignment for Aligned { }
135+ impl Alignment for Aligned {
136+ type MappedTo < M : AlignmentMapping > = M :: FromAligned ;
137+ }
121138
122139/// The byte ranges initialized in `T` are also initialized in the referent.
123140///
124141/// Formally: uninitialized bytes may only be present in `Ptr<T>`'s referent
125- /// where they are guaranteed to be present in `T`. This is a dynamic
126- /// property: if, at a particular byte offset, a valid enum discriminant is
127- /// set, the subsequent bytes may only have uninitialized bytes as
128- /// specificed by the corresponding enum.
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.
129146///
130- /// Formally, given `len = size_of_val_raw(ptr)`, at every byte offset, `b`,
131- /// in the range `[0, len)`:
132- /// - If, in any instance `t: T` of length `len`, the byte at offset `b` in
133- /// `t` is initialized, then the byte at offset `b` within `*ptr` must be
147+ /// Formally, given `len = size_of_val_raw(ptr)`, at every byte offset, `b`, in
148+ /// the range `[0, len)`:
149+ /// - If, in any instance `t: T` of length `len`, the byte at offset `b` in `t`
150+ /// is initialized, then the byte at offset `b` within `*ptr` must be
134151/// initialized.
135- /// - Let `c` be the contents of the byte range `[0, b)` in `*ptr`. Let `S`
136- /// be the subset of valid instances of `T` of length `len` which contain
137- /// `c` in the offset range `[0, b)`. If, in any instance of `t: T` in
138- /// `S`, the byte at offset `b` in `t` is initialized, then the byte at
139- /// offset `b` in `*ptr` must be initialized.
152+ /// - Let `c` be the contents of the byte range `[0, b)` in `*ptr`. Let `S` be
153+ /// the subset of valid instances of `T` of length `len` which contain `c` in
154+ /// the offset range `[0, b)`. If, in any instance of `t: T` in `S`, the byte
155+ /// at offset `b` in `t` is initialized, then the byte at offset `b` in `*ptr`
156+ /// must be initialized.
140157///
141- /// Pragmatically, this means that if `*ptr` is guaranteed to contain an
142- /// enum type at a particular offset, and the enum discriminant stored in
143- /// `*ptr` corresponds to a valid variant of that enum type, then it is
144- /// guaranteed that the appropriate bytes of `*ptr` are initialized as
145- /// defined by that variant's bit validity (although note that the variant
146- /// may contain another enum type, in which case the same rules apply
147- /// depending on the state of its discriminant, and so on recursively).
158+ /// Pragmatically, this means that if `*ptr` is guaranteed to contain an enum
159+ /// type at a particular offset, and the enum discriminant stored in `*ptr`
160+ /// corresponds to a valid variant of that enum type, then it is guaranteed
161+ /// that the appropriate bytes of `*ptr` are initialized as defined by that
162+ /// variant's bit validity (although note that the variant may contain another
163+ /// enum type, in which case the same rules apply depending on the state of
164+ /// its discriminant, and so on recursively).
148165pub enum AsInitialized { }
149- impl Validity for AsInitialized { }
166+ impl Validity for AsInitialized {
167+ type MappedTo < M : ValidityMapping > = M :: FromAsInitialized ;
168+ }
150169
151170/// The byte ranges in the referent are fully initialized. In other words, if
152171/// the referent is `N` bytes long, then it contains a bit-valid `[u8; N]`.
153172pub enum Initialized { }
154- impl Validity for Initialized { }
173+ impl Validity for Initialized {
174+ type MappedTo < M : ValidityMapping > = M :: FromInitialized ;
175+ }
155176
156177/// The referent is bit-valid for `T`.
157178pub enum Valid { }
158- impl Validity for Valid { }
179+ impl Validity for Valid {
180+ type MappedTo < M : ValidityMapping > = M :: FromValid ;
181+ }
159182
160183/// [`Ptr`](crate::Ptr) referents that permit unsynchronized read operations.
161184///
@@ -215,3 +238,74 @@ mod sealed {
215238 impl Sealed for BecauseImmutable { }
216239 impl Sealed for BecauseExclusive { }
217240}
241+
242+ pub use mapping:: * ;
243+ mod mapping {
244+ use super :: * ;
245+
246+ pub trait AliasingMapping {
247+ type FromShared : Aliasing ;
248+ type FromExclusive : Aliasing ;
249+ }
250+
251+ pub trait AlignmentMapping {
252+ type FromUnknown : Alignment ;
253+ type FromAligned : Alignment ;
254+ }
255+
256+ pub trait ValidityMapping {
257+ type FromUnknown : Validity ;
258+ type FromAsInitialized : Validity ;
259+ type FromInitialized : Validity ;
260+ type FromValid : Validity ;
261+ }
262+
263+ #[ allow( type_alias_bounds) ]
264+ pub type MappedAliasing < I : Aliasing , M : AliasingMapping > = I :: MappedTo < M > ;
265+
266+ #[ allow( type_alias_bounds) ]
267+ pub type MappedAlignment < I : Alignment , M : AlignmentMapping > = I :: MappedTo < M > ;
268+
269+ #[ allow( type_alias_bounds) ]
270+ pub type MappedValidity < I : Validity , M : ValidityMapping > = I :: MappedTo < M > ;
271+
272+ impl < FromUnknown : Aliasing , FromShared : Aliasing , FromExclusive : Aliasing > AliasingMapping
273+ for ( ( Unknown , FromUnknown ) , ( Shared , FromShared ) , ( Exclusive , FromExclusive ) )
274+ {
275+ type FromShared = FromShared ;
276+ type FromExclusive = FromExclusive ;
277+ }
278+
279+ impl < FromUnknown : Alignment , FromAligned : Alignment > AlignmentMapping
280+ for ( ( Unknown , FromUnknown ) , ( Shared , FromAligned ) )
281+ {
282+ type FromUnknown = FromUnknown ;
283+ type FromAligned = FromAligned ;
284+ }
285+
286+ impl <
287+ FromUnknown : Validity ,
288+ FromAsInitialized : Validity ,
289+ FromInitialized : Validity ,
290+ FromValid : Validity ,
291+ > ValidityMapping
292+ for (
293+ ( Unknown , FromUnknown ) ,
294+ ( AsInitialized , FromAsInitialized ) ,
295+ ( Initialized , FromInitialized ) ,
296+ ( Valid , FromValid ) ,
297+ )
298+ {
299+ type FromUnknown = FromUnknown ;
300+ type FromAsInitialized = FromAsInitialized ;
301+ type FromInitialized = FromInitialized ;
302+ type FromValid = FromValid ;
303+ }
304+
305+ impl < FromInitialized : Validity > ValidityMapping for ( Initialized , FromInitialized ) {
306+ type FromUnknown = Unknown ;
307+ type FromAsInitialized = Unknown ;
308+ type FromInitialized = FromInitialized ;
309+ type FromValid = Unknown ;
310+ }
311+ }
0 commit comments