@@ -2539,37 +2539,15 @@ pub unsafe trait TryFromBytes {
25392539 where
25402540 Self : Sized ,
25412541 {
2542- // Note that we have to call `is_bit_valid` on an exclusive-aliased
2543- // pointer since we don't require `Self: Immutable`. That's why we do `let
2544- // mut` and `Ptr::from_mut` here. See the doc comment on `is_bit_valid`
2545- // and the implementation of `TryFromBytes` for `UnsafeCell` for more
2546- // details.
2547- let mut candidate = match MaybeUninit :: < Self > :: read_from_bytes ( source) {
2542+ let candidate = match MaybeUninit :: < Self > :: read_from_bytes ( source) {
25482543 Ok ( candidate) => candidate,
25492544 Err ( e) => {
25502545 return Err ( TryReadError :: Size ( e. with_dst ( ) ) ) ;
25512546 }
25522547 } ;
2553- let c_ptr = Ptr :: from_mut ( & mut candidate) ;
2554- let c_ptr = c_ptr. transparent_wrapper_into_inner ( ) ;
2555- // SAFETY: `c_ptr` has no uninitialized sub-ranges because it derived
2556- // from `candidate`, which in turn derives from `source: &[u8]`.
2557- let c_ptr = unsafe { c_ptr. assume_validity :: < invariant:: Initialized > ( ) } ;
2558-
2559- // This call may panic. If that happens, it doesn't cause any soundness
2560- // issues, as we have not generated any invalid state which we need to
2561- // fix before returning.
2562- //
2563- // Note that one panic or post-monomorphization error condition is
2564- // calling `try_into_valid` (and thus `is_bit_valid`) with a shared
2565- // pointer when `Self: !Immutable`. Since `Self: Immutable`, this panic
2566- // condition will not happen.
2567- if !Self :: is_bit_valid ( c_ptr. forget_aligned ( ) ) {
2568- return Err ( ValidityError :: new ( source) . into ( ) ) ;
2569- }
2570-
2571- // SAFETY: We just validated that `candidate` contains a valid `Self`.
2572- Ok ( unsafe { candidate. assume_init ( ) } )
2548+ // SAFETY: `candidate` was copied from from `source: &[u8]`, so all of
2549+ // its bytes are initialized.
2550+ unsafe { try_read_from ( source, candidate) }
25732551 }
25742552
25752553 /// Attempts to read a `Self` from the prefix of the given `source`.
@@ -2622,37 +2600,15 @@ pub unsafe trait TryFromBytes {
26222600 where
26232601 Self : Sized ,
26242602 {
2625- // Note that we have to call `is_bit_valid` on an exclusive-aliased
2626- // pointer since we don't require `Self: Immutable`. That's why we do `let
2627- // mut` and `Ptr::from_mut` here. See the doc comment on `is_bit_valid`
2628- // and the implementation of `TryFromBytes` for `UnsafeCell` for more
2629- // details.
2630- let ( mut candidate, suffix) = match MaybeUninit :: < Self > :: read_from_prefix ( source) {
2603+ let ( candidate, suffix) = match MaybeUninit :: < Self > :: read_from_prefix ( source) {
26312604 Ok ( candidate) => candidate,
26322605 Err ( e) => {
26332606 return Err ( TryReadError :: Size ( e. with_dst ( ) ) ) ;
26342607 }
26352608 } ;
2636- let c_ptr = Ptr :: from_mut ( & mut candidate) ;
2637- let c_ptr = c_ptr. transparent_wrapper_into_inner ( ) ;
2638- // SAFETY: `c_ptr` has no uninitialized sub-ranges because it derived
2639- // from `candidate`, which in turn derives from `source: &[u8]`.
2640- let c_ptr = unsafe { c_ptr. assume_validity :: < invariant:: Initialized > ( ) } ;
2641-
2642- // This call may panic. If that happens, it doesn't cause any soundness
2643- // issues, as we have not generated any invalid state which we need to
2644- // fix before returning.
2645- //
2646- // Note that one panic or post-monomorphization error condition is
2647- // calling `try_into_valid` (and thus `is_bit_valid`) with a shared
2648- // pointer when `Self: !Immutable`. Since `Self: Immutable`, this panic
2649- // condition will not happen.
2650- if !Self :: is_bit_valid ( c_ptr. forget_aligned ( ) ) {
2651- return Err ( ValidityError :: new ( source) . into ( ) ) ;
2652- }
2653-
2654- // SAFETY: We just validated that `candidate` contains a valid `Self`.
2655- Ok ( ( unsafe { candidate. assume_init ( ) } , suffix) )
2609+ // SAFETY: `candidate` was copied from from `source: &[u8]`, so all of
2610+ // its bytes are initialized.
2611+ unsafe { try_read_from ( source, candidate) . map ( |slf| ( slf, suffix) ) }
26562612 }
26572613
26582614 /// Attempts to read a `Self` from the suffix of the given `source`.
@@ -2706,37 +2662,15 @@ pub unsafe trait TryFromBytes {
27062662 where
27072663 Self : Sized ,
27082664 {
2709- // Note that we have to call `is_bit_valid` on an exclusive-aliased
2710- // pointer since we don't require `Self: Immutable`. That's why we do `let
2711- // mut` and `Ptr::from_mut` here. See the doc comment on `is_bit_valid`
2712- // and the implementation of `TryFromBytes` for `UnsafeCell` for more
2713- // details.
2714- let ( prefix, mut candidate) = match MaybeUninit :: < Self > :: read_from_suffix ( source) {
2665+ let ( prefix, candidate) = match MaybeUninit :: < Self > :: read_from_suffix ( source) {
27152666 Ok ( candidate) => candidate,
27162667 Err ( e) => {
27172668 return Err ( TryReadError :: Size ( e. with_dst ( ) ) ) ;
27182669 }
27192670 } ;
2720- let c_ptr = Ptr :: from_mut ( & mut candidate) ;
2721- let c_ptr = c_ptr. transparent_wrapper_into_inner ( ) ;
2722- // SAFETY: `c_ptr` has no uninitialized sub-ranges because it derived
2723- // from `candidate`, which in turn derives from `source: &[u8]`.
2724- let c_ptr = unsafe { c_ptr. assume_validity :: < invariant:: Initialized > ( ) } ;
2725-
2726- // This call may panic. If that happens, it doesn't cause any soundness
2727- // issues, as we have not generated any invalid state which we need to
2728- // fix before returning.
2729- //
2730- // Note that one panic or post-monomorphization error condition is
2731- // calling `try_into_valid` (and thus `is_bit_valid`) with a shared
2732- // pointer when `Self: !Immutable`. Since `Self: Immutable`, this panic
2733- // condition will not happen.
2734- if !Self :: is_bit_valid ( c_ptr. forget_aligned ( ) ) {
2735- return Err ( ValidityError :: new ( source) . into ( ) ) ;
2736- }
2737-
2738- // SAFETY: We just validated that `candidate` contains a valid `Self`.
2739- Ok ( ( prefix, unsafe { candidate. assume_init ( ) } ) )
2671+ // SAFETY: `candidate` was copied from from `source: &[u8]`, so all of
2672+ // its bytes are initialized.
2673+ unsafe { try_read_from ( source, candidate) . map ( |slf| ( prefix, slf) ) }
27402674 }
27412675}
27422676
@@ -2795,6 +2729,38 @@ fn swap<T, U>((t, u): (T, U)) -> (U, T) {
27952729 ( u, t)
27962730}
27972731
2732+ /// # Safety
2733+ ///
2734+ /// All bytes of `candidate` must be initialized.
2735+ #[ inline( always) ]
2736+ unsafe fn try_read_from < S , T : TryFromBytes > (
2737+ source : S ,
2738+ mut candidate : MaybeUninit < T > ,
2739+ ) -> Result < T , TryReadError < S , T > > {
2740+ // We use `from_mut` despite not mutating via `c_ptr` so that we don't need
2741+ // to add a `T: Immutable` bound.
2742+ let c_ptr = Ptr :: from_mut ( & mut candidate) ;
2743+ let c_ptr = c_ptr. transparent_wrapper_into_inner ( ) ;
2744+ // SAFETY: `c_ptr` has no uninitialized sub-ranges because it derived from
2745+ // `candidate`, which the caller promises is entirely initialized.
2746+ let c_ptr = unsafe { c_ptr. assume_validity :: < invariant:: Initialized > ( ) } ;
2747+
2748+ // This call may panic. If that happens, it doesn't cause any soundness
2749+ // issues, as we have not generated any invalid state which we need to
2750+ // fix before returning.
2751+ //
2752+ // Note that one panic or post-monomorphization error condition is
2753+ // calling `try_into_valid` (and thus `is_bit_valid`) with a shared
2754+ // pointer when `Self: !Immutable`. Since `Self: Immutable`, this panic
2755+ // condition will not happen.
2756+ if !T :: is_bit_valid ( c_ptr. forget_aligned ( ) ) {
2757+ return Err ( ValidityError :: new ( source) . into ( ) ) ;
2758+ }
2759+
2760+ // SAFETY: We just validated that `candidate` contains a valid `T`.
2761+ Ok ( unsafe { candidate. assume_init ( ) } )
2762+ }
2763+
27982764/// Types for which a sequence of bytes all set to zero represents a valid
27992765/// instance of the type.
28002766///
0 commit comments