@@ -254,7 +254,7 @@ macro_rules! impl_for_transmute_from {
254254 // SAFETY: This macro ensures that `$repr` and `Self` have the same
255255 // size and bit validity. Thus, a bit-valid instance of `$repr` is
256256 // also a bit-valid instance of `Self`.
257- <$repr as TryFromBytes >:: is_bit_valid( candidate. transmute_sized ( ) )
257+ <$repr as TryFromBytes >:: is_bit_valid( candidate. transmute ( ) )
258258 }
259259 } ;
260260 (
@@ -694,13 +694,19 @@ macro_rules! static_assert_dst_is_not_zst {
694694
695695macro_rules! cast {
696696 ( ) => {
697- // SAFETY: `NonNull::as_ptr` returns a non-null pointer, so the argument
698- // to `NonNull::new_unchecked` is also non-null.
699697 |p| {
700- #[ allow( clippy:: as_conversions) ]
701- return core:: ptr:: NonNull :: new_unchecked( core:: ptr:: NonNull :: as_ptr( p) as * mut _) ;
698+ // SAFETY: `NonNull::as_ptr` returns a non-null pointer, so the
699+ // argument to `NonNull::new_unchecked` is also non-null.
700+ #[ allow( clippy:: as_conversions, unused_unsafe) ]
701+ #[ allow( clippy:: undocumented_unsafe_blocks) ] // Clippy false positive
702+ return unsafe {
703+ core:: ptr:: NonNull :: new_unchecked( core:: ptr:: NonNull :: as_ptr( p) as * mut _)
704+ } ;
702705 }
703706 } ;
707+ ( $p: ident) => {
708+ cast!( ) ( $p)
709+ } ;
704710}
705711
706712/// Implements `TransmuteFrom` and `SizeEq` for `T` and `$wrapper<T>`.
@@ -712,17 +718,27 @@ macro_rules! cast {
712718macro_rules! unsafe_impl_for_transparent_wrapper {
713719 ( T $( : ?$optbound: ident) ? => $wrapper: ident<T >) => {
714720 const _: ( ) = {
721+ use core:: ptr:: NonNull ;
715722 use crate :: pointer:: { TransmuteFrom , SizeEq , invariant:: Valid } ;
723+
716724 // SAFETY: The caller promises that `T` and `$wrapper<T>` have the
717725 // same bit validity.
718726 unsafe impl <T $( : ?$optbound) ?> TransmuteFrom <T , Valid , Valid > for $wrapper<T > { }
719727 // SAFETY: See previous safety comment.
720728 unsafe impl <T $( : ?$optbound) ?> TransmuteFrom <$wrapper<T >, Valid , Valid > for T { }
721729 // SAFETY: The caller promises that `T` and `$wrapper<T>` satisfy
722730 // `SizeEq`.
723- unsafe impl <T $( : ?$optbound) ?> SizeEq <T > for $wrapper<T > { }
731+ unsafe impl <T $( : ?$optbound) ?> SizeEq <T > for $wrapper<T > {
732+ fn cast_from_raw( t: NonNull <T >) -> NonNull <$wrapper<T >> {
733+ cast!( t)
734+ }
735+ }
724736 // SAFETY: See previous safety comment.
725- unsafe impl <T $( : ?$optbound) ?> SizeEq <$wrapper<T >> for T { }
737+ unsafe impl <T $( : ?$optbound) ?> SizeEq <$wrapper<T >> for T {
738+ fn cast_from_raw( t: NonNull <$wrapper<T >>) -> NonNull <T > {
739+ cast!( t)
740+ }
741+ }
726742 } ;
727743
728744 // So that this macro must be invoked inside `safety_comment!` or else
@@ -732,17 +748,57 @@ macro_rules! unsafe_impl_for_transparent_wrapper {
732748 } ;
733749}
734750
751+ macro_rules! impl_transitive_transmute_from {
752+ ( $( $tyvar: ident $( : ?$optbound: ident) ?) ? => $t: ty => $u: ty => $v: ty) => {
753+ const _: ( ) = {
754+ use core:: ptr:: NonNull ;
755+ use crate :: pointer:: { TransmuteFrom , SizeEq , invariant:: Valid } ;
756+
757+ // SAFETY: Since `$u: SizeEq<$t>` and `$v: SizeEq<U>`, this impl is
758+ // transitively sound.
759+ unsafe impl <$( $tyvar $( : ?$optbound) ?) ?> SizeEq <$t> for $v
760+ where
761+ $u: SizeEq <$t>,
762+ $v: SizeEq <$u>,
763+ {
764+ fn cast_from_raw( t: NonNull <$t>) -> NonNull <$v> {
765+ cast!( t)
766+ }
767+ }
768+
769+ // SAFETY: Since `$u: TransmuteFrom<$t, Valid, Valid>`, it is sound
770+ // to transmute a bit-valid `$t` to a bit-valid `$u`. Since `$v:
771+ // TransmuteFrom<$u, Valid, Valid>`, it is sound to transmute that
772+ // bit-valid `$u` to a bit-valid `$v`.
773+ unsafe impl <$( $tyvar $( : ?$optbound) ?) ?> TransmuteFrom <$t, Valid , Valid > for $v
774+ where
775+ $u: TransmuteFrom <$t, Valid , Valid >,
776+ $v: TransmuteFrom <$u, Valid , Valid >,
777+ { }
778+ } ;
779+ } ;
780+ }
781+
735782macro_rules! impl_size_eq {
736783 ( $t: ty, $u: ty) => {
737784 const _: ( ) = {
738785 use crate :: pointer:: SizeEq ;
786+ use core:: ptr:: NonNull ;
739787
740788 static_assert!( => mem:: size_of:: <$t>( ) == mem:: size_of:: <$u>( ) ) ;
741789
742790 // SAFETY: We've asserted that their sizes are equal.
743- unsafe impl SizeEq <$t> for $u { }
791+ unsafe impl SizeEq <$t> for $u {
792+ fn cast_from_raw( t: NonNull <$t>) -> NonNull <$u> {
793+ cast!( t)
794+ }
795+ }
744796 // SAFETY: We've asserted that their sizes are equal.
745- unsafe impl SizeEq <$u> for $t { }
797+ unsafe impl SizeEq <$u> for $t {
798+ fn cast_from_raw( u: NonNull <$u>) -> NonNull <$t> {
799+ cast!( u)
800+ }
801+ }
746802 } ;
747803 } ;
748804}
0 commit comments