@@ -187,13 +187,22 @@ pub mod invariant {
187187 /// Aliasing>::Variance<'a, T>` to inherit this variance.
188188 #[ doc( hidden) ]
189189 type Variance < ' a , T : ' a + ?Sized > ;
190+
191+ #[ doc( hidden) ]
192+ type MappedTo < M : AliasingMapping > : Aliasing ;
190193 }
191194
192195 /// The alignment invariant of a [`Ptr`][super::Ptr].
193- pub trait Alignment : Sealed { }
196+ pub trait Alignment : Sealed {
197+ #[ doc( hidden) ]
198+ type MappedTo < M : AlignmentMapping > : Alignment ;
199+ }
194200
195201 /// The validity invariant of a [`Ptr`][super::Ptr].
196- pub trait Validity : Sealed { }
202+ pub trait Validity : Sealed {
203+ #[ doc( hidden) ]
204+ type MappedTo < M : ValidityMapping > : Validity ;
205+ }
197206
198207 /// An [`Aliasing`] invariant which is either [`Shared`] or [`Exclusive`].
199208 ///
@@ -217,9 +226,15 @@ pub mod invariant {
217226 //
218227 // [1] https://doc.rust-lang.org/1.81.0/reference/subtyping.html#variance
219228 type Variance < ' a , T : ' a + ?Sized > = fn ( & ' a T ) -> & ' a T ;
229+
230+ type MappedTo < M : AliasingMapping > = M :: FromAny ;
231+ }
232+ impl Alignment for Any {
233+ type MappedTo < M : AlignmentMapping > = M :: FromAny ;
234+ }
235+ impl Validity for Any {
236+ type MappedTo < M : ValidityMapping > = M :: FromAny ;
220237 }
221- impl Alignment for Any { }
222- impl Validity for Any { }
223238
224239 /// The `Ptr<'a, T>` adheres to the aliasing rules of a `&'a T`.
225240 ///
@@ -234,6 +249,7 @@ pub mod invariant {
234249 impl Aliasing for Shared {
235250 const IS_EXCLUSIVE : bool = false ;
236251 type Variance < ' a , T : ' a + ?Sized > = & ' a T ;
252+ type MappedTo < M : AliasingMapping > = M :: FromShared ;
237253 }
238254 impl Reference for Shared { }
239255
@@ -246,13 +262,16 @@ pub mod invariant {
246262 impl Aliasing for Exclusive {
247263 const IS_EXCLUSIVE : bool = true ;
248264 type Variance < ' a , T : ' a + ?Sized > = & ' a mut T ;
265+ type MappedTo < M : AliasingMapping > = M :: FromExclusive ;
249266 }
250267 impl Reference for Exclusive { }
251268
252269 /// The referent is aligned: for `Ptr<T>`, the referent's address is a
253270 /// multiple of the `T`'s alignment.
254271 pub enum Aligned { }
255- impl Alignment for Aligned { }
272+ impl Alignment for Aligned {
273+ type MappedTo < M : AlignmentMapping > = M :: FromAligned ;
274+ }
256275
257276 /// The byte ranges initialized in `T` are also initialized in the referent.
258277 ///
@@ -281,17 +300,23 @@ pub mod invariant {
281300 /// may contain another enum type, in which case the same rules apply
282301 /// depending on the state of its discriminant, and so on recursively).
283302 pub enum AsInitialized { }
284- impl Validity for AsInitialized { }
303+ impl Validity for AsInitialized {
304+ type MappedTo < M : ValidityMapping > = M :: FromAsInitialized ;
305+ }
285306
286307 /// The byte ranges in the referent are fully initialized. In other words,
287308 /// if the referent is `N` bytes long, then it contains a bit-valid `[u8;
288309 /// N]`.
289310 pub enum Initialized { }
290- impl Validity for Initialized { }
311+ impl Validity for Initialized {
312+ type MappedTo < M : ValidityMapping > = M :: FromInitialized ;
313+ }
291314
292315 /// The referent is bit-valid for `T`.
293316 pub enum Valid { }
294- impl Validity for Valid { }
317+ impl Validity for Valid {
318+ type MappedTo < M : ValidityMapping > = M :: FromValid ;
319+ }
295320
296321 use sealed:: Sealed ;
297322 mod sealed {
@@ -312,6 +337,79 @@ pub mod invariant {
312337
313338 impl < A : Sealed , AA : Sealed , V : Sealed > Sealed for ( A , AA , V ) { }
314339 }
340+
341+ pub use mapping:: * ;
342+ mod mapping {
343+ use super :: * ;
344+
345+ pub trait AliasingMapping {
346+ type FromAny : Aliasing ;
347+ type FromShared : Aliasing ;
348+ type FromExclusive : Aliasing ;
349+ }
350+
351+ pub trait AlignmentMapping {
352+ type FromAny : Alignment ;
353+ type FromAligned : Alignment ;
354+ }
355+
356+ pub trait ValidityMapping {
357+ type FromAny : Validity ;
358+ type FromAsInitialized : Validity ;
359+ type FromInitialized : Validity ;
360+ type FromValid : Validity ;
361+ }
362+
363+ #[ allow( type_alias_bounds) ]
364+ pub type MappedAliasing < I : Aliasing , M : AliasingMapping > = I :: MappedTo < M > ;
365+
366+ #[ allow( type_alias_bounds) ]
367+ pub type MappedAlignment < I : Alignment , M : AlignmentMapping > = I :: MappedTo < M > ;
368+
369+ #[ allow( type_alias_bounds) ]
370+ pub type MappedValidity < I : Validity , M : ValidityMapping > = I :: MappedTo < M > ;
371+
372+ impl < FromAny : Aliasing , FromShared : Aliasing , FromExclusive : Aliasing > AliasingMapping
373+ for ( ( Any , FromAny ) , ( Shared , FromShared ) , ( Exclusive , FromExclusive ) )
374+ {
375+ type FromAny = FromAny ;
376+ type FromShared = FromShared ;
377+ type FromExclusive = FromExclusive ;
378+ }
379+
380+ impl < FromAny : Alignment , FromAligned : Alignment > AlignmentMapping
381+ for ( ( Any , FromAny ) , ( Shared , FromAligned ) )
382+ {
383+ type FromAny = FromAny ;
384+ type FromAligned = FromAligned ;
385+ }
386+
387+ impl <
388+ FromAny : Validity ,
389+ FromAsInitialized : Validity ,
390+ FromInitialized : Validity ,
391+ FromValid : Validity ,
392+ > ValidityMapping
393+ for (
394+ ( Any , FromAny ) ,
395+ ( AsInitialized , FromAsInitialized ) ,
396+ ( Initialized , FromInitialized ) ,
397+ ( Valid , FromValid ) ,
398+ )
399+ {
400+ type FromAny = FromAny ;
401+ type FromAsInitialized = FromAsInitialized ;
402+ type FromInitialized = FromInitialized ;
403+ type FromValid = FromValid ;
404+ }
405+
406+ impl < FromInitialized : Validity > ValidityMapping for ( Initialized , FromInitialized ) {
407+ type FromAny = Any ;
408+ type FromAsInitialized = Any ;
409+ type FromInitialized = FromInitialized ;
410+ type FromValid = Any ;
411+ }
412+ }
315413}
316414
317415pub ( crate ) use invariant:: * ;
@@ -911,7 +1009,8 @@ mod _casts {
9111009 pub unsafe fn cast_unsized < U : ' a + ?Sized , F : FnOnce ( * mut T ) -> * mut U > (
9121010 self ,
9131011 cast : F ,
914- ) -> Ptr < ' a , U , ( I :: Aliasing , Any , Any ) > {
1012+ ) -> Ptr < ' a , U , ( I :: Aliasing , Any , MappedValidity < I :: Validity , ( Initialized , Initialized ) > ) >
1013+ {
9151014 let ptr = cast ( self . as_inner ( ) . as_non_null ( ) . as_ptr ( ) ) ;
9161015
9171016 // SAFETY: Caller promises that `cast` returns a pointer whose
@@ -967,7 +1066,13 @@ mod _casts {
9671066 // not happen.
9681067 // 7. `ptr`, trivially, conforms to the alignment invariant of
9691068 // `Any`.
970- // 8. `ptr`, trivially, conforms to the validity invariant of `Any`.
1069+ // 8. If `I::Validity = Any`, `AsInitialized`, or `Valid`, the
1070+ // output validity invariant is `Any`. `ptr` trivially conforms
1071+ // to this invariant. If `I::Validity = Initialized`, the output
1072+ // validity invariant is `Initialized`. Regardless of what subset
1073+ // of `self`'s referent is referred to by `ptr`, if all of
1074+ // `self`'s referent is initialized, then the same holds of
1075+ // `ptr`'s referent.
9711076 unsafe { Ptr :: new ( ptr) }
9721077 }
9731078 }
@@ -1010,14 +1115,7 @@ mod _casts {
10101115 } )
10111116 } ;
10121117
1013- let ptr = ptr. bikeshed_recall_aligned ( ) ;
1014-
1015- // SAFETY: `ptr`'s referent begins as `Initialized`, denoting that
1016- // all bytes of the referent are initialized bytes. The referent
1017- // type is then casted to `[u8]`, whose only validity invariant is
1018- // that its bytes are initialized. This validity invariant is
1019- // satisfied by the `Initialized` invariant on the starting `ptr`.
1020- unsafe { ptr. assume_validity :: < Valid > ( ) }
1118+ ptr. bikeshed_recall_aligned ( ) . bikeshed_recall_valid ( )
10211119 }
10221120 }
10231121
@@ -1250,12 +1348,7 @@ mod _project {
12501348
12511349 // SAFETY: This method has the same safety preconditions as
12521350 // `cast_unsized`.
1253- let ptr = unsafe { self . cast_unsized ( projector) } ;
1254-
1255- // SAFETY: If all of the bytes of `self` are initialized (as
1256- // promised by `I: Invariants<Validity = Initialized>`), then any
1257- // subset of those bytes are also all initialized.
1258- unsafe { ptr. assume_validity :: < Initialized > ( ) }
1351+ unsafe { self . cast_unsized ( projector) }
12591352 }
12601353 }
12611354
0 commit comments