@@ -114,7 +114,7 @@ safety_comment! {
114
114
} ) ;
115
115
}
116
116
117
- impl_size_eq ! ( bool , u8 ) ;
117
+ impl_size_compat ! ( bool , u8 ) ;
118
118
119
119
safety_comment ! {
120
120
/// SAFETY:
@@ -145,7 +145,7 @@ safety_comment! {
145
145
} ) ;
146
146
}
147
147
148
- impl_size_eq ! ( char , Unalign <u32 >) ;
148
+ impl_size_compat ! ( char , Unalign <u32 >) ;
149
149
150
150
safety_comment ! {
151
151
/// SAFETY:
@@ -179,39 +179,13 @@ safety_comment! {
179
179
} ) ;
180
180
}
181
181
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 ] ) ;
199
183
200
184
macro_rules! unsafe_impl_try_from_bytes_for_nonzero {
201
185
( $( $nonzero: ident[ $prim: ty] ) ,* ) => {
202
186
$(
203
187
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>) ;
215
189
let n = n. transmute:: <Unalign <$prim>, invariant:: Valid , _>( ) ;
216
190
$nonzero:: new( n. read_unaligned( ) . into_inner( ) ) . is_some( )
217
191
} ) ;
@@ -429,58 +403,75 @@ mod atomics {
429
403
macro_rules! unsafe_impl_transmute_from_for_atomic {
430
404
( $( $( $tyvar: ident) ? => $atomic: ty [ $prim: ty] ) ,* ) => {
431
405
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 } ;
434
408
435
409
$(
436
410
#[ allow( unused_unsafe) ] // Force the caller to call this macro inside `safety_comment!`.
437
411
const _: ( ) = unsafe { } ;
438
412
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.
441
417
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.
444
422
unsafe impl <$( $tyvar) ?> TransmuteFrom <$prim, Valid , Valid > for $atomic { }
445
423
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) }
451
432
}
452
433
}
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) }
458
440
}
459
441
}
442
+
460
443
// SAFETY: The caller promised that `$atomic` and `$prim`
461
444
// 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.
463
447
//
464
448
// [1] Per https://doc.rust-lang.org/1.85.0/std/cell/struct.UnsafeCell.html#memory-layout:
465
449
//
466
450
// `UnsafeCell<T>` has the same in-memory representation as
467
451
// its inner type `T`. A consequence of this guarantee is that
468
452
// 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) }
472
458
}
473
459
}
474
460
// 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) }
478
466
}
479
467
}
480
468
481
469
// SAFETY: The caller promised that `$atomic` and `$prim`
482
470
// 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.
484
475
//
485
476
// [1] Per https://doc.rust-lang.org/1.85.0/std/cell/struct.UnsafeCell.html#memory-layout:
486
477
//
0 commit comments