@@ -14,7 +14,6 @@ use core::{
14
14
} ;
15
15
16
16
use super :: * ;
17
- use crate :: pointer:: PtrInner ;
18
17
19
18
safety_comment ! {
20
19
/// SAFETY:
@@ -115,7 +114,7 @@ safety_comment! {
115
114
} ) ;
116
115
}
117
116
118
- impl_size_eq ! ( bool , u8 ) ;
117
+ impl_size_compat ! ( bool , u8 ) ;
119
118
120
119
safety_comment ! {
121
120
/// SAFETY:
@@ -146,7 +145,7 @@ safety_comment! {
146
145
} ) ;
147
146
}
148
147
149
- impl_size_eq ! ( char , Unalign <u32 >) ;
148
+ impl_size_compat ! ( char , Unalign <u32 >) ;
150
149
151
150
safety_comment ! {
152
151
/// SAFETY:
@@ -180,14 +179,13 @@ safety_comment! {
180
179
} ) ;
181
180
}
182
181
183
- impl_size_eq ! ( str , [ u8 ] ) ;
182
+ impl_size_compat ! ( str , [ u8 ] ) ;
184
183
185
184
macro_rules! unsafe_impl_try_from_bytes_for_nonzero {
186
185
( $( $nonzero: ident[ $prim: ty] ) ,* ) => {
187
186
$(
188
187
unsafe_impl!( => TryFromBytes for $nonzero; |n| {
189
- impl_size_eq!( $nonzero, Unalign <$prim>) ;
190
-
188
+ impl_size_compat!( $nonzero, Unalign <$prim>) ;
191
189
let n = n. transmute:: <Unalign <$prim>, invariant:: Valid , _>( ) ;
192
190
$nonzero:: new( n. read_unaligned( ) . into_inner( ) ) . is_some( )
193
191
} ) ;
@@ -405,23 +403,27 @@ mod atomics {
405
403
macro_rules! unsafe_impl_transmute_from_for_atomic {
406
404
( $( $( $tyvar: ident) ? => $atomic: ty [ $prim: ty] ) ,* ) => {
407
405
const _: ( ) = {
408
- use core:: cell:: UnsafeCell ;
409
- use crate :: pointer:: { TransmuteFrom , SizeEq , invariant:: Valid } ;
406
+ use core:: { cell:: UnsafeCell } ;
407
+ use crate :: pointer:: { TransmuteFrom , PtrInner , SizeCompat , invariant:: Valid } ;
410
408
411
409
$(
412
410
#[ allow( unused_unsafe) ] // Force the caller to call this macro inside `safety_comment!`.
413
411
const _: ( ) = unsafe { } ;
414
412
415
- // SAFETY: The caller promised that `$atomic` and `$prim` have
416
- // 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.
417
417
unsafe impl <$( $tyvar) ?> TransmuteFrom <$atomic, Valid , Valid > for $prim { }
418
- // SAFETY: The caller promised that `$atomic` and `$prim` have
419
- // 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.
420
422
unsafe impl <$( $tyvar) ?> TransmuteFrom <$prim, Valid , Valid > for $atomic { }
421
423
422
- // SAFETY: The caller promised that `$atomic` and `$prim`
423
- // have the same size.
424
- unsafe impl <$ ( $tyvar ) ?> SizeEq <$atomic> for $prim {
424
+ // SAFETY: See inline safety comment.
425
+ unsafe impl <$ ( $tyvar ) ?> SizeCompat <$atomic> for $prim {
426
+ # [ inline ( always ) ]
425
427
fn cast_from_raw( a: PtrInner <' _, $atomic>) -> PtrInner <' _, $prim> {
426
428
// SAFETY: The caller promised that `$atomic` and `$prim`
427
429
// have the same size. Thus, this cast preserves
@@ -430,29 +432,34 @@ mod atomics {
430
432
}
431
433
}
432
434
// SAFETY: See previous safety comment.
433
- unsafe impl <$( $tyvar) ?> SizeEq <$prim> for $atomic {
435
+ unsafe impl <$( $tyvar) ?> SizeCompat <$prim> for $atomic {
436
+ #[ inline( always) ]
434
437
fn cast_from_raw( p: PtrInner <' _, $prim>) -> PtrInner <' _, $atomic> {
435
438
// SAFETY: See previous safety comment.
436
439
unsafe { cast!( p) }
437
440
}
438
441
}
442
+
439
443
// SAFETY: The caller promised that `$atomic` and `$prim`
440
444
// have the same size. `UnsafeCell<T>` has the same size as
441
- // `T` [1].
445
+ // `T` [1]. Thus, this cast preserves address, referent
446
+ // size, and provenance.
442
447
//
443
448
// [1] Per https://doc.rust-lang.org/1.85.0/std/cell/struct.UnsafeCell.html#memory-layout:
444
449
//
445
450
// `UnsafeCell<T>` has the same in-memory representation as
446
451
// its inner type `T`. A consequence of this guarantee is that
447
452
// it is possible to convert between `T` and `UnsafeCell<T>`.
448
- unsafe impl <$( $tyvar) ?> SizeEq <$atomic> for UnsafeCell <$prim> {
453
+ unsafe impl <$( $tyvar) ?> SizeCompat <$atomic> for UnsafeCell <$prim> {
454
+ #[ inline( always) ]
449
455
fn cast_from_raw( a: PtrInner <' _, $atomic>) -> PtrInner <' _, UnsafeCell <$prim>> {
450
456
// SAFETY: See previous safety comment.
451
457
unsafe { cast!( a) }
452
458
}
453
459
}
454
460
// SAFETY: See previous safety comment.
455
- unsafe impl <$( $tyvar) ?> SizeEq <UnsafeCell <$prim>> for $atomic {
461
+ unsafe impl <$( $tyvar) ?> SizeCompat <UnsafeCell <$prim>> for $atomic {
462
+ #[ inline( always) ]
456
463
fn cast_from_raw( p: PtrInner <' _, UnsafeCell <$prim>>) -> PtrInner <' _, $atomic> {
457
464
// SAFETY: See previous safety comment.
458
465
unsafe { cast!( p) }
@@ -461,7 +468,10 @@ mod atomics {
461
468
462
469
// SAFETY: The caller promised that `$atomic` and `$prim`
463
470
// have the same bit validity. `UnsafeCell<T>` has the same
464
- // 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.
465
475
//
466
476
// [1] Per https://doc.rust-lang.org/1.85.0/std/cell/struct.UnsafeCell.html#memory-layout:
467
477
//
0 commit comments