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