@@ -2821,6 +2821,40 @@ pub unsafe trait TryFromBytes {
2821
2821
// its bytes are initialized.
2822
2822
unsafe { try_read_from ( source, candidate) . map ( |slf| ( prefix, slf) ) }
2823
2823
}
2824
+
2825
+ // TODO: Write tests for this method
2826
+ #[ cfg( feature = "std" ) ]
2827
+ #[ inline( always) ]
2828
+ fn try_read_from_io < R > ( mut src : R ) -> io:: Result < Self >
2829
+ where
2830
+ Self : Sized ,
2831
+ R : io:: Read ,
2832
+ {
2833
+ // NOTE(#2319, #2320): We do `buf.zero()` separately rather than
2834
+ // constructing `let buf = CoreMaybeUninit::zeroed()` because, if `Self`
2835
+ // contains padding bytes, then a typed copy of `CoreMaybeUninit<Self>`
2836
+ // will not necessarily preserve zeros written to those padding byte
2837
+ // locations, and so `buf` could contain uninitialized bytes.
2838
+ let mut buf = CoreMaybeUninit :: < Self > :: uninit ( ) ;
2839
+ buf. zero ( ) ;
2840
+
2841
+ let ptr = Ptr :: from_mut ( & mut buf) ;
2842
+ // SAFETY: After `buf.zero()`, `buf` consists entirely of initialized,
2843
+ // zeroed bytes. Since `MaybeUninit` has no validity requirements, `ptr`
2844
+ // cannot be used to write values which will violate `buf`'s bit
2845
+ // validity. Since `ptr` has `Exclusive` aliasing, nothing other than
2846
+ // `ptr` may be used to mutate `ptr`'s referent, and so its bit validity
2847
+ // cannot be violated even though `buf` may have more permissive bit
2848
+ // validity than `ptr`.
2849
+ let ptr = unsafe { ptr. assume_validity :: < invariant:: Initialized > ( ) } ;
2850
+ let ptr = ptr. as_bytes :: < BecauseExclusive > ( ) ;
2851
+ src. read_exact ( ptr. as_mut ( ) ) ?;
2852
+
2853
+ // SAFETY: `buf` entirely consists of initialized bytes.
2854
+ //
2855
+ // TODO: What error type should we return from this method?
2856
+ unsafe { try_read_from ( ( ) , buf) . map_err ( |err| todo ! ( ) ) }
2857
+ }
2824
2858
}
2825
2859
2826
2860
#[ inline( always) ]
0 commit comments