@@ -805,6 +805,17 @@ pub unsafe trait KnownLayout {
805805 // resulting size would not fit in a `usize`.
806806 meta. size_for_metadata ( Self :: LAYOUT )
807807 }
808+
809+ #[ doc( hidden) ]
810+ #[ must_use]
811+ #[ inline( always) ]
812+ fn cast_from_raw < P : KnownLayout < PointerMetadata = Self :: PointerMetadata > + ?Sized > (
813+ ptr : NonNull < P > ,
814+ ) -> NonNull < Self > {
815+ let data = ptr. cast :: < u8 > ( ) ;
816+ let meta = P :: pointer_to_metadata ( ptr. as_ptr ( ) ) ;
817+ Self :: raw_from_ptr_len ( data, meta)
818+ }
808819}
809820
810821/// The metadata associated with a [`KnownLayout`] type.
@@ -2843,29 +2854,43 @@ unsafe fn try_read_from<S, T: TryFromBytes>(
28432854 // We use `from_mut` despite not mutating via `c_ptr` so that we don't need
28442855 // to add a `T: Immutable` bound.
28452856 let c_ptr = Ptr :: from_mut ( & mut candidate) ;
2846- let c_ptr = c_ptr. transparent_wrapper_into_inner ( ) ;
28472857 // SAFETY: `c_ptr` has no uninitialized sub-ranges because it derived from
28482858 // `candidate`, which the caller promises is entirely initialized. Since
28492859 // `candidate` is a `MaybeUninit`, it has no validity requirements, and so
2850- // no values written to ` c_ptr` can violate its validity. Since `c_ptr` has
2851- // ` Exclusive` aliasing, no mutations may happen except via `c_ptr` so long
2852- // as it is live, so we don't need to worry about the fact that `c_ptr` may
2853- // have more restricted validity than `candidate`.
2860+ // no values written to an `Initialized` ` c_ptr` can violate its validity.
2861+ // Since `c_ptr` has ` Exclusive` aliasing, no mutations may happen except
2862+ // via `c_ptr` so long as it is live, so we don't need to worry about the
2863+ // fact that `c_ptr` may have more restricted validity than `candidate`.
28542864 let c_ptr = unsafe { c_ptr. assume_validity :: < invariant:: Initialized > ( ) } ;
2865+ let c_ptr = c_ptr. transmute ( ) ;
28552866
2867+ // Since we don't have `T: KnownLayout`, we hack around that by using
2868+ // `Wrapping<T>`, which implements `KnownLayout` even if `T` doesn't.
2869+ //
28562870 // This call may panic. If that happens, it doesn't cause any soundness
2857- // issues, as we have not generated any invalid state which we need to
2858- // fix before returning.
2871+ // issues, as we have not generated any invalid state which we need to fix
2872+ // before returning.
28592873 //
2860- // Note that one panic or post-monomorphization error condition is
2861- // calling `try_into_valid` (and thus `is_bit_valid`) with a shared
2862- // pointer when `Self: !Immutable`. Since `Self: Immutable`, this panic
2863- // condition will not happen.
2864- if !T :: is_bit_valid ( c_ptr. forget_aligned ( ) ) {
2874+ // Note that one panic or post-monomorphization error condition is calling
2875+ // `try_into_valid` (and thus `is_bit_valid`) with a shared pointer when
2876+ // `Self: !Immutable`. Since `Self: Immutable`, this panic condition will
2877+ // not happen.
2878+ if !Wrapping :: < T > :: is_bit_valid ( c_ptr. forget_aligned ( ) ) {
28652879 return Err ( ValidityError :: new ( source) . into ( ) ) ;
28662880 }
28672881
2868- // SAFETY: We just validated that `candidate` contains a valid `T`.
2882+ fn _assert_same_size_and_validity < T > ( )
2883+ where
2884+ Wrapping < T > : pointer:: TransmuteFrom < T , invariant:: Valid , invariant:: Valid > ,
2885+ T : pointer:: TransmuteFrom < Wrapping < T > , invariant:: Valid , invariant:: Valid > ,
2886+ {
2887+ }
2888+
2889+ _assert_same_size_and_validity :: < T > ( ) ;
2890+
2891+ // SAFETY: We just validated that `candidate` contains a valid
2892+ // `Wrapping<T>`, which has the same size and bit validity as `T`, as
2893+ // guaranteed by the preceding type assertion.
28692894 Ok ( unsafe { candidate. assume_init ( ) } )
28702895}
28712896
@@ -3552,7 +3577,7 @@ pub unsafe trait FromBytes: FromZeros {
35523577 {
35533578 static_assert_dst_is_not_zst ! ( Self ) ;
35543579 match Ptr :: from_ref ( source) . try_cast_into_no_leftover :: < _ , BecauseImmutable > ( None ) {
3555- Ok ( ptr) => Ok ( ptr. bikeshed_recall_valid ( ) . as_ref ( ) ) ,
3580+ Ok ( ptr) => Ok ( ptr. recall_validity ( ) . as_ref ( ) ) ,
35563581 Err ( err) => Err ( err. map_src ( |src| src. as_ref ( ) ) ) ,
35573582 }
35583583 }
@@ -3788,7 +3813,7 @@ pub unsafe trait FromBytes: FromZeros {
37883813 {
37893814 static_assert_dst_is_not_zst ! ( Self ) ;
37903815 match Ptr :: from_mut ( source) . try_cast_into_no_leftover :: < _ , BecauseExclusive > ( None ) {
3791- Ok ( ptr) => Ok ( ptr. bikeshed_recall_valid ( ) . as_mut ( ) ) ,
3816+ Ok ( ptr) => Ok ( ptr. recall_validity ( ) . as_mut ( ) ) ,
37923817 Err ( err) => Err ( err. map_src ( |src| src. as_mut ( ) ) ) ,
37933818 }
37943819 }
@@ -4027,7 +4052,7 @@ pub unsafe trait FromBytes: FromZeros {
40274052 let source = Ptr :: from_ref ( source) ;
40284053 let maybe_slf = source. try_cast_into_no_leftover :: < _ , BecauseImmutable > ( Some ( count) ) ;
40294054 match maybe_slf {
4030- Ok ( slf) => Ok ( slf. bikeshed_recall_valid ( ) . as_ref ( ) ) ,
4055+ Ok ( slf) => Ok ( slf. recall_validity ( ) . as_ref ( ) ) ,
40314056 Err ( err) => Err ( err. map_src ( |s| s. as_ref ( ) ) ) ,
40324057 }
40334058 }
@@ -4258,7 +4283,9 @@ pub unsafe trait FromBytes: FromZeros {
42584283 let source = Ptr :: from_mut ( source) ;
42594284 let maybe_slf = source. try_cast_into_no_leftover :: < _ , BecauseImmutable > ( Some ( count) ) ;
42604285 match maybe_slf {
4261- Ok ( slf) => Ok ( slf. bikeshed_recall_valid ( ) . as_mut ( ) ) ,
4286+ Ok ( slf) => Ok ( slf
4287+ . recall_validity :: < _ , ( _ , ( _ , ( BecauseExclusive , BecauseExclusive ) ) ) > ( )
4288+ . as_mut ( ) ) ,
42624289 Err ( err) => Err ( err. map_src ( |s| s. as_mut ( ) ) ) ,
42634290 }
42644291 }
@@ -4716,7 +4743,7 @@ fn ref_from_prefix_suffix<T: FromBytes + KnownLayout + Immutable + ?Sized>(
47164743 let ( slf, prefix_suffix) = Ptr :: from_ref ( source)
47174744 . try_cast_into :: < _ , BecauseImmutable > ( cast_type, meta)
47184745 . map_err ( |err| err. map_src ( |s| s. as_ref ( ) ) ) ?;
4719- Ok ( ( slf. bikeshed_recall_valid ( ) . as_ref ( ) , prefix_suffix. as_ref ( ) ) )
4746+ Ok ( ( slf. recall_validity ( ) . as_ref ( ) , prefix_suffix. as_ref ( ) ) )
47204747}
47214748
47224749/// Interprets the given affix of the given bytes as a `&mut Self` without
@@ -4728,15 +4755,15 @@ fn ref_from_prefix_suffix<T: FromBytes + KnownLayout + Immutable + ?Sized>(
47284755/// If there are insufficient bytes, or if that affix of `source` is not
47294756/// appropriately aligned, this returns `Err`.
47304757#[ inline( always) ]
4731- fn mut_from_prefix_suffix < T : FromBytes + KnownLayout + ?Sized > (
4758+ fn mut_from_prefix_suffix < T : FromBytes + IntoBytes + KnownLayout + ?Sized > (
47324759 source : & mut [ u8 ] ,
47334760 meta : Option < T :: PointerMetadata > ,
47344761 cast_type : CastType ,
47354762) -> Result < ( & mut T , & mut [ u8 ] ) , CastError < & mut [ u8 ] , T > > {
47364763 let ( slf, prefix_suffix) = Ptr :: from_mut ( source)
47374764 . try_cast_into :: < _ , BecauseExclusive > ( cast_type, meta)
47384765 . map_err ( |err| err. map_src ( |s| s. as_mut ( ) ) ) ?;
4739- Ok ( ( slf. bikeshed_recall_valid ( ) . as_mut ( ) , prefix_suffix. as_mut ( ) ) )
4766+ Ok ( ( slf. recall_validity ( ) . as_mut ( ) , prefix_suffix. as_mut ( ) ) )
47404767}
47414768
47424769/// Analyzes whether a type is [`IntoBytes`].
0 commit comments