@@ -568,15 +568,33 @@ pub unsafe trait AsBytes {
568
568
/// `as_bytes` provides access to the bytes of this value as an immutable
569
569
/// byte slice.
570
570
fn as_bytes ( & self ) -> & [ u8 ] {
571
- // TODO(#61): Add a "SAFETY" comment and remove this `allow`.
572
- #[ allow( clippy:: undocumented_unsafe_blocks) ]
573
- unsafe {
574
- // Note that this method does not have a `Self: Sized` bound;
575
- // `size_of_val` works for unsized values too.
576
- let len = mem:: size_of_val ( self ) ;
577
- let slf: * const Self = self ;
578
- slice:: from_raw_parts ( slf. cast :: < u8 > ( ) , len)
579
- }
571
+ // Note that this method does not have a `Self: Sized` bound;
572
+ // `size_of_val` works for unsized values too.
573
+ let len = mem:: size_of_val ( self ) ;
574
+ let slf: * const Self = self ;
575
+
576
+ // SAFETY:
577
+ // - `slf.cast::<u8>()` is valid for reads for `len *
578
+ // mem::size_of::<u8>()` many bytes because...
579
+ // - `slf` is the same pointer as `self`, and `self` is a reference
580
+ // which points to an object whose size is `len`. Thus...
581
+ // - The entire region of `len` bytes starting at `slf` is contained
582
+ // within a single allocation.
583
+ // - `slf` is non-null.
584
+ // - `slf` is trivially aligned to `align_of::<u8>() == 1`.
585
+ // - `Self: AsBytes` ensures that all of the bytes of `slf` are
586
+ // initialized.
587
+ // - Since `slf` is derived from `self`, and `self` is an immutable
588
+ // reference, the only other references to this memory region that
589
+ // could exist are other immutable references, and those don't allow
590
+ // mutation.
591
+ //
592
+ // TODO(#8): Update `AsRef` docs to require that `Self` doesn't allow
593
+ // interior mutability so that this bullet point is actually true.
594
+ // - The total size of the resulting slice is no larger than
595
+ // `isize::MAX` because no allocation produced by safe code can be
596
+ // larger than `isize::MAX`.
597
+ unsafe { slice:: from_raw_parts ( slf. cast :: < u8 > ( ) , len) }
580
598
}
581
599
582
600
/// Gets the bytes of this value mutably.
@@ -587,15 +605,30 @@ pub unsafe trait AsBytes {
587
605
where
588
606
Self : FromBytes ,
589
607
{
590
- // TODO(#61): Add a "SAFETY" comment and remove this `allow`.
591
- #[ allow( clippy:: undocumented_unsafe_blocks) ]
592
- unsafe {
593
- // Note that this method does not have a `Self: Sized` bound;
594
- // `size_of_val` works for unsized values too.
595
- let len = mem:: size_of_val ( self ) ;
596
- let slf: * mut Self = self ;
597
- slice:: from_raw_parts_mut ( slf. cast :: < u8 > ( ) , len)
598
- }
608
+ // Note that this method does not have a `Self: Sized` bound;
609
+ // `size_of_val` works for unsized values too.
610
+ let len = mem:: size_of_val ( self ) ;
611
+ let slf: * mut Self = self ;
612
+
613
+ // SAFETY:
614
+ // - `slf.cast::<u8>()` is valid for reads and writes for `len *
615
+ // mem::size_of::<u8>()` many bytes because...
616
+ // - `slf` is the same pointer as `self`, and `self` is a reference
617
+ // which points to an object whose size is `len`. Thus...
618
+ // - The entire region of `len` bytes starting at `slf` is contained
619
+ // within a single allocation.
620
+ // - `slf` is non-null.
621
+ // - `slf` is trivially aligned to `align_of::<u8>() == 1`.
622
+ // - `Self: AsBytes` ensures that all of the bytes of `slf` are
623
+ // initialized.
624
+ // - `Self: FromBytes` ensures that no write to this memory region
625
+ // could result in it containing an invalid `Self`.
626
+ // - Since `slf` is derived from `self`, and `self` is a mutable
627
+ // reference, no other references to this memory region can exist.
628
+ // - The total size of the resulting slice is no larger than
629
+ // `isize::MAX` because no allocation produced by safe code can be
630
+ // larger than `isize::MAX`.
631
+ unsafe { slice:: from_raw_parts_mut ( slf. cast :: < u8 > ( ) , len) }
599
632
}
600
633
601
634
/// Writes a copy of `self` to `bytes`.
0 commit comments