@@ -651,9 +651,7 @@ impl_for_transparent_wrapper!(T: ?Sized + Unaligned => Unaligned for UnsafeCell<
651
651
assert_unaligned ! ( UnsafeCell <( ) >, UnsafeCell <u8 >) ;
652
652
653
653
// SAFETY: See safety comment in `is_bit_valid` impl.
654
- //
655
- // TODO(#5): Try to add `T: ?Sized` bound.
656
- unsafe impl < T : TryFromBytes > TryFromBytes for UnsafeCell < T > {
654
+ unsafe impl < T : TryFromBytes + ?Sized > TryFromBytes for UnsafeCell < T > {
657
655
#[ allow( clippy:: missing_inline_in_public_items) ]
658
656
fn only_derive_is_allowed_to_implement_this_trait ( )
659
657
where
@@ -682,56 +680,11 @@ unsafe impl<T: TryFromBytes> TryFromBytes for UnsafeCell<T> {
682
680
// chance to fix it quickly.
683
681
let c = candidate. into_exclusive_or_post_monomorphization_error ( ) ;
684
682
685
- // We wrap in `Unalign` here so that we can get a vanilla Rust reference
686
- // below, which in turn allows us to call `UnsafeCell::get_mut`.
687
- //
688
- // SAFETY:
689
- // - `.cast` preserves address. `Unalign` and `MaybeUninit` both have
690
- // the same size as the types they wrap [1]. Thus, this cast will
691
- // preserve the size of the pointer. As a result, the cast will
692
- // address the same bytes as `c`.
693
- // - `.cast` preserves provenance.
694
- // - Since both the source and destination types are wrapped in
695
- // `UnsafeCell`, all bytes of both types are inside of `UnsafeCell`s,
696
- // and so the byte ranges covered by `UnsafeCell`s are identical in
697
- // both types. Since the pointers refer to the same byte ranges,
698
- // the same is true of the pointers' referents as well.
699
- //
700
- // [1] Per https://doc.rust-lang.org/stable/core/mem/union.MaybeUninit.html#layout-1:
701
- //
702
- // MaybeUninit<T> is guaranteed to have the same size, alignment, and
703
- // ABI as T.
704
- let c = unsafe {
705
- c. cast_unsized ( |c : * mut UnsafeCell < T > | c. cast :: < UnsafeCell < Unalign < MaybeUninit < T > > > > ( ) )
706
- } ;
707
- // SAFETY: `MaybeUninit` has no validity requirements.
708
- let c = unsafe { c. assume_valid ( ) } ;
709
- let c = c. bikeshed_recall_aligned ( ) ;
710
- // This is the crucial step at which we use `UnsafeCell::get_mut` to go
711
- // from `UnsafeCell<U>` to `U` (where `U = Unalign<MaybeUninit<T>>`).
712
- // Now that we've gotten rid of the `UnsafeCell`, we can delegate to
713
- // `T::is_bit_valid`.
714
- let c: & mut Unalign < MaybeUninit < T > > = c. as_mut ( ) . get_mut ( ) ;
715
- // This converts from an aligned `Unalign<MaybeUninit<T>>` pointer to an
716
- // unaligned `MaybeUninit<T>` pointer.
717
- let c: Ptr < ' _ , MaybeUninit < T > , _ > = Ptr :: from_mut ( c) . transparent_wrapper_into_inner ( ) ;
718
- let c: Ptr < ' _ , T , _ > = c. transparent_wrapper_into_inner ( ) ;
719
-
720
- // SAFETY: The original `candidate` argument has `Initialized` validity.
721
- // None of the subsequent operations modify the memory itself, and so
722
- // that guarantee is still upheld.
723
- let c = unsafe { c. assume_initialized ( ) } ;
724
- // Confirm that `Maybe` is a type alias for `Ptr` with the validity
725
- // invariant `Initialized`. Our safety proof depends upon this
726
- // invariant, and it might change at some point. If that happens, we
727
- // want this function to stop compiling.
728
- let _: Ptr < ' _ , UnsafeCell < T > , ( _ , _ , invariant:: Initialized ) > = candidate;
729
-
730
683
// SAFETY: Since `UnsafeCell<T>` and `T` have the same layout and bit
731
684
// validity, `UnsafeCell<T>` is bit-valid exactly when its wrapped `T`
732
685
// is. Thus, this is a sound implementation of
733
686
// `UnsafeCell::is_bit_valid`.
734
- T :: is_bit_valid ( c. forget_exclusive ( ) )
687
+ T :: is_bit_valid ( c. get_mut ( ) )
735
688
}
736
689
}
737
690
0 commit comments