@@ -467,15 +467,33 @@ pub unsafe trait AsBytes {
467
467
/// `as_bytes` provides access to the bytes of this value as an immutable
468
468
/// byte slice.
469
469
fn as_bytes ( & self ) -> & [ u8 ] {
470
- // TODO(#61): Add a "SAFETY" comment and remove this `allow`.
471
- #[ allow( clippy:: undocumented_unsafe_blocks) ]
472
- unsafe {
473
- // Note that this method does not have a `Self: Sized` bound;
474
- // `size_of_val` works for unsized values too.
475
- let len = mem:: size_of_val ( self ) ;
476
- let slf: * const Self = self ;
477
- slice:: from_raw_parts ( slf. cast :: < u8 > ( ) , len)
478
- }
470
+ // Note that this method does not have a `Self: Sized` bound;
471
+ // `size_of_val` works for unsized values too.
472
+ let len = mem:: size_of_val ( self ) ;
473
+ let slf: * const Self = self ;
474
+
475
+ // SAFETY:
476
+ // - `slf.cast::<u8>()` is valid for reads for `len *
477
+ // mem::size_of::<u8>()` many bytes because...
478
+ // - `slf` is the same pointer as `self`, and `self` is a reference
479
+ // which points to an object whose size is `len`. Thus...
480
+ // - The entire region of `len` bytes starting at `slf` is contained
481
+ // within a single allocation.
482
+ // - `slf` is non-null.
483
+ // - `slf` is trivially aligned to `align_of::<u8>() == 1`.
484
+ // - `Self: AsBytes` ensures that all of the bytes of `slf` are
485
+ // initialized.
486
+ // - Since `slf` is derived from `self`, and `self` is an immutable
487
+ // reference, the only other references to this memory region that
488
+ // could exist are other immutable references, and those don't allow
489
+ // mutation.
490
+ //
491
+ // TODO(#8): Update `AsRef` docs to require that `Self` doesn't allow
492
+ // interior mutability so that this bullet point is actually true.
493
+ // - The total size of the resulting slice is no larger than
494
+ // `isize::MAX` because no allocation produced by safe code can be
495
+ // larger than `isize::MAX`.
496
+ unsafe { slice:: from_raw_parts ( slf. cast :: < u8 > ( ) , len) }
479
497
}
480
498
481
499
/// Gets the bytes of this value mutably.
@@ -486,15 +504,30 @@ pub unsafe trait AsBytes {
486
504
where
487
505
Self : FromBytes ,
488
506
{
489
- // TODO(#61): Add a "SAFETY" comment and remove this `allow`.
490
- #[ allow( clippy:: undocumented_unsafe_blocks) ]
491
- unsafe {
492
- // Note that this method does not have a `Self: Sized` bound;
493
- // `size_of_val` works for unsized values too.
494
- let len = mem:: size_of_val ( self ) ;
495
- let slf: * mut Self = self ;
496
- slice:: from_raw_parts_mut ( slf. cast :: < u8 > ( ) , len)
497
- }
507
+ // Note that this method does not have a `Self: Sized` bound;
508
+ // `size_of_val` works for unsized values too.
509
+ let len = mem:: size_of_val ( self ) ;
510
+ let slf: * mut Self = self ;
511
+
512
+ // SAFETY:
513
+ // - `slf.cast::<u8>()` is valid for reads and writes for `len *
514
+ // mem::size_of::<u8>()` many bytes because...
515
+ // - `slf` is the same pointer as `self`, and `self` is a reference
516
+ // which points to an object whose size is `len`. Thus...
517
+ // - The entire region of `len` bytes starting at `slf` is contained
518
+ // within a single allocation.
519
+ // - `slf` is non-null.
520
+ // - `slf` is trivially aligned to `align_of::<u8>() == 1`.
521
+ // - `Self: AsBytes` ensures that all of the bytes of `slf` are
522
+ // initialized.
523
+ // - `Self: FromBytes` ensures that no write to this memory region
524
+ // could result in it containing an invalid `Self`.
525
+ // - Since `slf` is derived from `self`, and `self` is a mutable
526
+ // reference, no other references to this memory region can exist.
527
+ // - The total size of the resulting slice is no larger than
528
+ // `isize::MAX` because no allocation produced by safe code can be
529
+ // larger than `isize::MAX`.
530
+ unsafe { slice:: from_raw_parts_mut ( slf. cast :: < u8 > ( ) , len) }
498
531
}
499
532
500
533
/// Writes a copy of `self` to `bytes`.
0 commit comments