11#[ cfg( feature = "std" ) ]
22use super :: Writer ;
33
4- use core:: { mem, cmp , ptr, usize} ;
4+ use core:: { cmp , mem:: { self , MaybeUninit } , ptr, usize} ;
55
66#[ cfg( feature = "std" ) ]
7- use std:: io :: IoSliceMut ;
7+ use std:: fmt ;
88
99use alloc:: { vec:: Vec , boxed:: Box } ;
1010
@@ -72,13 +72,15 @@ pub trait BufMut {
7272 /// let mut buf = Vec::with_capacity(16);
7373 ///
7474 /// unsafe {
75- /// buf.bytes_mut()[0] = b'h';
76- /// buf.bytes_mut()[1] = b'e';
75+ /// // MaybeUninit::as_mut_ptr
76+ /// buf.bytes_mut()[0].as_mut_ptr().write(b'h');
77+ /// buf.bytes_mut()[1].as_mut_ptr().write(b'e');
7778 ///
7879 /// buf.advance_mut(2);
7980 ///
80- /// buf.bytes_mut()[0] = b'l';
81- /// buf.bytes_mut()[1..3].copy_from_slice(b"lo");
81+ /// buf.bytes_mut()[0].as_mut_ptr().write(b'l');
82+ /// buf.bytes_mut()[1].as_mut_ptr().write(b'l');
83+ /// buf.bytes_mut()[2].as_mut_ptr().write(b'o');
8284 ///
8385 /// buf.advance_mut(3);
8486 /// }
@@ -139,13 +141,15 @@ pub trait BufMut {
139141 /// let mut buf = Vec::with_capacity(16);
140142 ///
141143 /// unsafe {
142- /// buf.bytes_mut()[0] = b'h';
143- /// buf.bytes_mut()[1] = b'e';
144+ /// // MaybeUninit::as_mut_ptr
145+ /// buf.bytes_mut()[0].as_mut_ptr().write(b'h');
146+ /// buf.bytes_mut()[1].as_mut_ptr().write(b'e');
144147 ///
145148 /// buf.advance_mut(2);
146149 ///
147- /// buf.bytes_mut()[0] = b'l';
148- /// buf.bytes_mut()[1..3].copy_from_slice(b"lo");
150+ /// buf.bytes_mut()[0].as_mut_ptr().write(b'l');
151+ /// buf.bytes_mut()[1].as_mut_ptr().write(b'l');
152+ /// buf.bytes_mut()[2].as_mut_ptr().write(b'o');
149153 ///
150154 /// buf.advance_mut(3);
151155 /// }
@@ -161,7 +165,7 @@ pub trait BufMut {
161165 /// `bytes_mut` returning an empty slice implies that `remaining_mut` will
162166 /// return 0 and `remaining_mut` returning 0 implies that `bytes_mut` will
163167 /// return an empty slice.
164- unsafe fn bytes_mut ( & mut self ) -> & mut [ u8 ] ;
168+ fn bytes_mut ( & mut self ) -> & mut [ MaybeUninit < u8 > ] ;
165169
166170 /// Fills `dst` with potentially multiple mutable slices starting at `self`'s
167171 /// current position.
@@ -192,13 +196,13 @@ pub trait BufMut {
192196 ///
193197 /// [`readv`]: http://man7.org/linux/man-pages/man2/readv.2.html
194198 #[ cfg( feature = "std" ) ]
195- unsafe fn bytes_vectored_mut < ' a > ( & ' a mut self , dst : & mut [ IoSliceMut < ' a > ] ) -> usize {
199+ fn bytes_vectored_mut < ' a > ( & ' a mut self , dst : & mut [ IoSliceMut < ' a > ] ) -> usize {
196200 if dst. is_empty ( ) {
197201 return 0 ;
198202 }
199203
200204 if self . has_remaining_mut ( ) {
201- dst[ 0 ] = IoSliceMut :: new ( self . bytes_mut ( ) ) ;
205+ dst[ 0 ] = IoSliceMut :: from ( self . bytes_mut ( ) ) ;
202206 1
203207 } else {
204208 0
@@ -238,7 +242,7 @@ pub trait BufMut {
238242
239243 ptr:: copy_nonoverlapping (
240244 s. as_ptr ( ) ,
241- d. as_mut_ptr ( ) ,
245+ d. as_mut_ptr ( ) as * mut u8 ,
242246 l) ;
243247 }
244248
@@ -280,7 +284,7 @@ pub trait BufMut {
280284
281285 ptr:: copy_nonoverlapping (
282286 src[ off..] . as_ptr ( ) ,
283- dst. as_mut_ptr ( ) ,
287+ dst. as_mut_ptr ( ) as * mut u8 ,
284288 cnt) ;
285289
286290 off += cnt;
@@ -931,12 +935,12 @@ impl<T: BufMut + ?Sized> BufMut for &mut T {
931935 ( * * self ) . remaining_mut ( )
932936 }
933937
934- unsafe fn bytes_mut ( & mut self ) -> & mut [ u8 ] {
938+ fn bytes_mut ( & mut self ) -> & mut [ MaybeUninit < u8 > ] {
935939 ( * * self ) . bytes_mut ( )
936940 }
937941
938942 #[ cfg( feature = "std" ) ]
939- unsafe fn bytes_vectored_mut < ' b > ( & ' b mut self , dst : & mut [ IoSliceMut < ' b > ] ) -> usize {
943+ fn bytes_vectored_mut < ' b > ( & ' b mut self , dst : & mut [ IoSliceMut < ' b > ] ) -> usize {
940944 ( * * self ) . bytes_vectored_mut ( dst)
941945 }
942946
@@ -950,12 +954,12 @@ impl<T: BufMut + ?Sized> BufMut for Box<T> {
950954 ( * * self ) . remaining_mut ( )
951955 }
952956
953- unsafe fn bytes_mut ( & mut self ) -> & mut [ u8 ] {
957+ fn bytes_mut ( & mut self ) -> & mut [ MaybeUninit < u8 > ] {
954958 ( * * self ) . bytes_mut ( )
955959 }
956960
957961 #[ cfg( feature = "std" ) ]
958- unsafe fn bytes_vectored_mut < ' b > ( & ' b mut self , dst : & mut [ IoSliceMut < ' b > ] ) -> usize {
962+ fn bytes_vectored_mut < ' b > ( & ' b mut self , dst : & mut [ IoSliceMut < ' b > ] ) -> usize {
959963 ( * * self ) . bytes_vectored_mut ( dst)
960964 }
961965
@@ -971,8 +975,9 @@ impl BufMut for &mut [u8] {
971975 }
972976
973977 #[ inline]
974- unsafe fn bytes_mut ( & mut self ) -> & mut [ u8 ] {
975- self
978+ fn bytes_mut ( & mut self ) -> & mut [ MaybeUninit < u8 > ] {
979+ // MaybeUninit is repr(transparent), so safe to transmute
980+ unsafe { mem:: transmute ( & mut * * self ) }
976981 }
977982
978983 #[ inline]
@@ -1003,7 +1008,7 @@ impl BufMut for Vec<u8> {
10031008 }
10041009
10051010 #[ inline]
1006- unsafe fn bytes_mut ( & mut self ) -> & mut [ u8 ] {
1011+ fn bytes_mut ( & mut self ) -> & mut [ MaybeUninit < u8 > ] {
10071012 use core:: slice;
10081013
10091014 if self . capacity ( ) == self . len ( ) {
@@ -1013,11 +1018,54 @@ impl BufMut for Vec<u8> {
10131018 let cap = self . capacity ( ) ;
10141019 let len = self . len ( ) ;
10151020
1016- let ptr = self . as_mut_ptr ( ) ;
1017- & mut slice:: from_raw_parts_mut ( ptr, cap) [ len..]
1021+ let ptr = self . as_mut_ptr ( ) as * mut MaybeUninit < u8 > ;
1022+ unsafe {
1023+ & mut slice:: from_raw_parts_mut ( ptr, cap) [ len..]
1024+ }
10181025 }
10191026}
10201027
10211028// The existence of this function makes the compiler catch if the BufMut
10221029// trait is "object-safe" or not.
10231030fn _assert_trait_object ( _b : & dyn BufMut ) { }
1031+
1032+ // ===== impl IoSliceMut =====
1033+
1034+ /// A buffer type used for `readv`.
1035+ ///
1036+ /// This is a wrapper around an `std::io::IoSliceMut`, but does not expose
1037+ /// the inner bytes in a safe API, as they may point at uninitialized memory.
1038+ ///
1039+ /// This is `repr(transparent)` of the `std::io::IoSliceMut`, so it is valid to
1040+ /// transmute them. However, as the memory might be uninitialized, care must be
1041+ /// taken to not *read* the internal bytes, only *write* to them.
1042+ #[ repr( transparent) ]
1043+ #[ cfg( feature = "std" ) ]
1044+ pub struct IoSliceMut < ' a > ( std:: io:: IoSliceMut < ' a > ) ;
1045+
1046+ #[ cfg( feature = "std" ) ]
1047+ impl fmt:: Debug for IoSliceMut < ' _ > {
1048+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
1049+ f. debug_struct ( "IoSliceMut" )
1050+ . field ( "len" , & self . 0 . len ( ) )
1051+ . finish ( )
1052+ }
1053+ }
1054+
1055+ #[ cfg( feature = "std" ) ]
1056+ impl < ' a > From < & ' a mut [ u8 ] > for IoSliceMut < ' a > {
1057+ fn from ( buf : & ' a mut [ u8 ] ) -> IoSliceMut < ' a > {
1058+ IoSliceMut ( std:: io:: IoSliceMut :: new ( buf) )
1059+ }
1060+ }
1061+
1062+ #[ cfg( feature = "std" ) ]
1063+ impl < ' a > From < & ' a mut [ MaybeUninit < u8 > ] > for IoSliceMut < ' a > {
1064+ fn from ( buf : & ' a mut [ MaybeUninit < u8 > ] ) -> IoSliceMut < ' a > {
1065+ IoSliceMut ( std:: io:: IoSliceMut :: new ( unsafe {
1066+ // We don't look at the contents, and `std::io::IoSliceMut`
1067+ // doesn't either.
1068+ mem:: transmute :: < & ' a mut [ MaybeUninit < u8 > ] , & ' a mut [ u8 ] > ( buf)
1069+ } ) )
1070+ }
1071+ }
0 commit comments