@@ -114,7 +114,7 @@ safety_comment! {
114114 } ) ;
115115}
116116
117- impl_size_eq ! ( bool , u8 ) ;
117+ impl_size_compat ! ( bool , u8 ) ;
118118
119119safety_comment ! {
120120 /// SAFETY:
@@ -145,7 +145,7 @@ safety_comment! {
145145 } ) ;
146146}
147147
148- impl_size_eq ! ( char , Unalign <u32 >) ;
148+ impl_size_compat ! ( char , Unalign <u32 >) ;
149149
150150safety_comment ! {
151151 /// SAFETY:
@@ -179,39 +179,13 @@ safety_comment! {
179179 } ) ;
180180}
181181
182- // SAFETY: `str` and `[u8]` have the same layout [1].
183- //
184- // [1] Per https://doc.rust-lang.org/1.81.0/reference/type-layout.html#str-layout:
185- //
186- // String slices are a UTF-8 representation of characters that have the same
187- // layout as slices of type `[u8]`.
188- unsafe impl pointer:: SizeEq < str > for [ u8 ] {
189- fn cast_from_raw ( s : NonNull < str > ) -> NonNull < [ u8 ] > {
190- cast ! ( s)
191- }
192- }
193- // SAFETY: See previous safety comment.
194- unsafe impl pointer:: SizeEq < [ u8 ] > for str {
195- fn cast_from_raw ( bytes : NonNull < [ u8 ] > ) -> NonNull < str > {
196- cast ! ( bytes)
197- }
198- }
182+ impl_size_compat ! ( str , [ u8 ] ) ;
199183
200184macro_rules! unsafe_impl_try_from_bytes_for_nonzero {
201185 ( $( $nonzero: ident[ $prim: ty] ) ,* ) => {
202186 $(
203187 unsafe_impl!( => TryFromBytes for $nonzero; |n| {
204- unsafe impl pointer:: SizeEq <$nonzero> for Unalign <$prim> {
205- fn cast_from_raw( n: NonNull <$nonzero>) -> NonNull <Unalign <$prim>> {
206- cast!( n)
207- }
208- }
209- unsafe impl pointer:: SizeEq <Unalign <$prim>> for $nonzero {
210- fn cast_from_raw( p: NonNull <Unalign <$prim>>) -> NonNull <$nonzero> {
211- cast!( p)
212- }
213- }
214-
188+ impl_size_compat!( $nonzero, Unalign <$prim>) ;
215189 let n = n. transmute:: <Unalign <$prim>, invariant:: Valid , _>( ) ;
216190 $nonzero:: new( n. read_unaligned( ) . into_inner( ) ) . is_some( )
217191 } ) ;
@@ -429,58 +403,75 @@ mod atomics {
429403 macro_rules! unsafe_impl_transmute_from_for_atomic {
430404 ( $( $( $tyvar: ident) ? => $atomic: ty [ $prim: ty] ) ,* ) => {
431405 const _: ( ) = {
432- use core:: { cell:: UnsafeCell , ptr :: NonNull } ;
433- use crate :: pointer:: { TransmuteFrom , SizeEq , invariant:: Valid } ;
406+ use core:: { cell:: UnsafeCell } ;
407+ use crate :: pointer:: { TransmuteFrom , PtrInner , SizeCompat , invariant:: Valid } ;
434408
435409 $(
436410 #[ allow( unused_unsafe) ] // Force the caller to call this macro inside `safety_comment!`.
437411 const _: ( ) = unsafe { } ;
438412
439- // SAFETY: The caller promised that `$atomic` and `$prim` have
440- // the same size and bit validity.
413+ // SAFETY: The caller promised that `$atomic` and `$prim`
414+ // have the same size and bit validity. As a result of size
415+ // equality, both impls of `SizeCompat::cast_from_raw`
416+ // preserve referent size exactly.
441417 unsafe impl <$( $tyvar) ?> TransmuteFrom <$atomic, Valid , Valid > for $prim { }
442- // SAFETY: The caller promised that `$atomic` and `$prim` have
443- // the same size and bit validity.
418+ // SAFETY: The caller promised that `$atomic` and `$prim`
419+ // have the same size and bit validity. As a result of size
420+ // equality, both impls of `SizeCompat::cast_from_raw`
421+ // preserve referent size exactly.
444422 unsafe impl <$( $tyvar) ?> TransmuteFrom <$prim, Valid , Valid > for $atomic { }
445423
446- // SAFETY: THe caller promised that `$atomic` and `$prim`
447- // have the same size.
448- unsafe impl <$( $tyvar) ?> SizeEq <$atomic> for $prim {
449- fn cast_from_raw( a: NonNull <$atomic>) -> NonNull <$prim> {
450- cast!( a)
424+ // SAFETY: See inline safety comment.
425+ unsafe impl <$( $tyvar) ?> SizeCompat <$atomic> for $prim {
426+ #[ inline( always) ]
427+ fn cast_from_raw( a: PtrInner <' _, $atomic>) -> PtrInner <' _, $prim> {
428+ // SAFETY: The caller promised that `$atomic` and `$prim`
429+ // have the same size. Thus, this cast preserves
430+ // address, referent size, and provenance.
431+ unsafe { cast!( a) }
451432 }
452433 }
453- // SAFETY: THe caller promised that `$atomic` and `$prim`
454- // have the same size.
455- unsafe impl <$( $tyvar) ?> SizeEq <$prim> for $atomic {
456- fn cast_from_raw( p: NonNull <$prim>) -> NonNull <$atomic> {
457- cast!( p)
434+ // SAFETY: See previous safety comment.
435+ unsafe impl <$( $tyvar) ?> SizeCompat <$prim> for $atomic {
436+ #[ inline( always) ]
437+ fn cast_from_raw( p: PtrInner <' _, $prim>) -> PtrInner <' _, $atomic> {
438+ // SAFETY: See previous safety comment.
439+ unsafe { cast!( p) }
458440 }
459441 }
442+
460443 // SAFETY: The caller promised that `$atomic` and `$prim`
461444 // have the same size. `UnsafeCell<T>` has the same size as
462- // `T` [1].
445+ // `T` [1]. Thus, this cast preserves address, referent
446+ // size, and provenance.
463447 //
464448 // [1] Per https://doc.rust-lang.org/1.85.0/std/cell/struct.UnsafeCell.html#memory-layout:
465449 //
466450 // `UnsafeCell<T>` has the same in-memory representation as
467451 // its inner type `T`. A consequence of this guarantee is that
468452 // it is possible to convert between `T` and `UnsafeCell<T>`.
469- unsafe impl <$( $tyvar) ?> SizeEq <$atomic> for UnsafeCell <$prim> {
470- fn cast_from_raw( a: NonNull <$atomic>) -> NonNull <UnsafeCell <$prim>> {
471- cast!( a)
453+ unsafe impl <$( $tyvar) ?> SizeCompat <$atomic> for UnsafeCell <$prim> {
454+ #[ inline( always) ]
455+ fn cast_from_raw( a: PtrInner <' _, $atomic>) -> PtrInner <' _, UnsafeCell <$prim>> {
456+ // SAFETY: See previous safety comment.
457+ unsafe { cast!( a) }
472458 }
473459 }
474460 // SAFETY: See previous safety comment.
475- unsafe impl <$( $tyvar) ?> SizeEq <UnsafeCell <$prim>> for $atomic {
476- fn cast_from_raw( p: NonNull <UnsafeCell <$prim>>) -> NonNull <$atomic> {
477- cast!( p)
461+ unsafe impl <$( $tyvar) ?> SizeCompat <UnsafeCell <$prim>> for $atomic {
462+ #[ inline( always) ]
463+ fn cast_from_raw( p: PtrInner <' _, UnsafeCell <$prim>>) -> PtrInner <' _, $atomic> {
464+ // SAFETY: See previous safety comment.
465+ unsafe { cast!( p) }
478466 }
479467 }
480468
481469 // SAFETY: The caller promised that `$atomic` and `$prim`
482470 // have the same bit validity. `UnsafeCell<T>` has the same
483- // bit validity as `T` [1].
471+ // bit validity as `T` [1]. `UnsafeCell<T>` also has the
472+ // same size as `T` [1], and so both impls of
473+ // `SizeCompat::cast_from_raw` preserve referent size
474+ // exactly.
484475 //
485476 // [1] Per https://doc.rust-lang.org/1.85.0/std/cell/struct.UnsafeCell.html#memory-layout:
486477 //
0 commit comments