@@ -6,7 +6,7 @@ mod tests;
66use crate :: cmp;
77use crate :: fmt:: { self , Debug , Formatter } ;
88use crate :: io:: { Result , Write } ;
9- use crate :: mem:: MaybeUninit ;
9+ use crate :: mem:: { self , MaybeUninit } ;
1010
1111/// A borrowed byte buffer which is incrementally filled and initialized.
1212///
@@ -23,9 +23,9 @@ use crate::mem::MaybeUninit;
2323/// ```
2424///
2525/// A `BorrowedBuf` is created around some existing data (or capacity for data) via a unique reference
26- /// (`&mut`). The `BorrowedBuf` can be configured (e.g., using `clear` or `set_init`), but otherwise
27- /// is read-only . To write into the buffer, use `unfilled` to create a `BorrowedCursor`. The cursor
28- /// has write-only access to the unfilled portion of the buffer (you can think of it like a
26+ /// (`&mut`). The `BorrowedBuf` can be configured (e.g., using `clear` or `set_init`), but cannot be
27+ /// directly written . To write into the buffer, use `unfilled` to create a `BorrowedCursor`. The cursor
28+ /// has write-only access to the unfilled portion of the buffer (you can think of it as a
2929/// write-only iterator).
3030///
3131/// The lifetime `'data` is a bound on the lifetime of the underlying data.
@@ -55,7 +55,7 @@ impl<'data> From<&'data mut [u8]> for BorrowedBuf<'data> {
5555 let len = slice. len ( ) ;
5656
5757 BorrowedBuf {
58- //SAFETY: initialized data never becoming uninitialized is an invariant of BorrowedBuf
58+ // SAFETY: initialized data never becoming uninitialized is an invariant of BorrowedBuf
5959 buf : unsafe { ( slice as * mut [ u8 ] ) . as_uninit_slice_mut ( ) . unwrap ( ) } ,
6060 filled : 0 ,
6161 init : len,
@@ -95,14 +95,21 @@ impl<'data> BorrowedBuf<'data> {
9595 /// Returns a shared reference to the filled portion of the buffer.
9696 #[ inline]
9797 pub fn filled ( & self ) -> & [ u8 ] {
98- //SAFETY: We only slice the filled part of the buffer, which is always valid
98+ // SAFETY: We only slice the filled part of the buffer, which is always valid
9999 unsafe { MaybeUninit :: slice_assume_init_ref ( & self . buf [ 0 ..self . filled ] ) }
100100 }
101101
102102 /// Returns a cursor over the unfilled part of the buffer.
103103 #[ inline]
104- pub fn unfilled < ' this > ( & ' this mut self ) -> BorrowedCursor < ' this , ' data > {
105- BorrowedCursor { start : self . filled , buf : self }
104+ pub fn unfilled < ' this > ( & ' this mut self ) -> BorrowedCursor < ' this > {
105+ BorrowedCursor {
106+ start : self . filled ,
107+ // SAFETY: we never assign into `BorrowedCursor::buf`, so treating its
108+ // lifetime covariantly is safe.
109+ buf : unsafe {
110+ mem:: transmute :: < & ' this mut BorrowedBuf < ' data > , & ' this mut BorrowedBuf < ' this > > ( self )
111+ } ,
112+ }
106113 }
107114
108115 /// Clears the buffer, resetting the filled region to empty.
@@ -141,25 +148,37 @@ impl<'data> BorrowedBuf<'data> {
141148/// `BorrowedBuf` and can no longer be accessed or re-written by the cursor. I.e., the cursor tracks
142149/// the unfilled part of the underlying `BorrowedBuf`.
143150///
144- /// The `'buf` lifetime is a bound on the lifetime of the underlying buffer. `'data` is a bound on
145- /// that buffer's underlying data .
151+ /// The lifetime `'a` is a bound on the lifetime of the underlying buffer (which means it is a bound
152+ /// on the data in that buffer by transitivity) .
146153#[ derive( Debug ) ]
147- pub struct BorrowedCursor < ' buf , ' data > {
154+ pub struct BorrowedCursor < ' a > {
148155 /// The underlying buffer.
149- buf : & ' buf mut BorrowedBuf < ' data > ,
156+ // Safety invariant: we treat the type of buf as covariant in the lifetime of `BorrowedBuf` when
157+ // we create a `BorrowedCursor`. This is only safe if we never replace `buf` by assigning into
158+ // it, so don't do that!
159+ buf : & ' a mut BorrowedBuf < ' a > ,
150160 /// The length of the filled portion of the underlying buffer at the time of the cursor's
151161 /// creation.
152162 start : usize ,
153163}
154164
155- impl < ' buf , ' data > BorrowedCursor < ' buf , ' data > {
156- /// Clone this cursor.
165+ impl < ' a > BorrowedCursor < ' a > {
166+ /// Reborrow this cursor by cloning it with a smaller lifetime .
157167 ///
158- /// Since a cursor maintains unique access to its underlying buffer, the cloned cursor is not
159- /// accessible while the clone is alive .
168+ /// Since a cursor maintains unique access to its underlying buffer, the borrowed cursor is
169+ /// not accessible while the new cursor exists .
160170 #[ inline]
161- pub fn clone < ' this > ( & ' this mut self ) -> BorrowedCursor < ' this , ' data > {
162- BorrowedCursor { buf : self . buf , start : self . start }
171+ pub fn reborrow < ' this > ( & ' this mut self ) -> BorrowedCursor < ' this > {
172+ BorrowedCursor {
173+ // SAFETY: we never assign into `BorrowedCursor::buf`, so treating its
174+ // lifetime covariantly is safe.
175+ buf : unsafe {
176+ mem:: transmute :: < & ' this mut BorrowedBuf < ' a > , & ' this mut BorrowedBuf < ' this > > (
177+ self . buf ,
178+ )
179+ } ,
180+ start : self . start ,
181+ }
163182 }
164183
165184 /// Returns the available space in the cursor.
@@ -170,8 +189,8 @@ impl<'buf, 'data> BorrowedCursor<'buf, 'data> {
170189
171190 /// Returns the number of bytes written to this cursor since it was created from a `BorrowedBuf`.
172191 ///
173- /// Note that if this cursor is a clone of another, then the count returned is the count written
174- /// via either cursor, not the count since the cursor was cloned .
192+ /// Note that if this cursor is a reborrowed clone of another, then the count returned is the
193+ /// count written via either cursor, not the count since the cursor was reborrowed .
175194 #[ inline]
176195 pub fn written ( & self ) -> usize {
177196 self . buf . filled - self . start
@@ -180,14 +199,14 @@ impl<'buf, 'data> BorrowedCursor<'buf, 'data> {
180199 /// Returns a shared reference to the initialized portion of the cursor.
181200 #[ inline]
182201 pub fn init_ref ( & self ) -> & [ u8 ] {
183- //SAFETY: We only slice the initialized part of the buffer, which is always valid
202+ // SAFETY: We only slice the initialized part of the buffer, which is always valid
184203 unsafe { MaybeUninit :: slice_assume_init_ref ( & self . buf . buf [ self . buf . filled ..self . buf . init ] ) }
185204 }
186205
187206 /// Returns a mutable reference to the initialized portion of the cursor.
188207 #[ inline]
189208 pub fn init_mut ( & mut self ) -> & mut [ u8 ] {
190- //SAFETY: We only slice the initialized part of the buffer, which is always valid
209+ // SAFETY: We only slice the initialized part of the buffer, which is always valid
191210 unsafe {
192211 MaybeUninit :: slice_assume_init_mut ( & mut self . buf . buf [ self . buf . filled ..self . buf . init ] )
193212 }
@@ -275,7 +294,7 @@ impl<'buf, 'data> BorrowedCursor<'buf, 'data> {
275294 }
276295}
277296
278- impl < ' buf , ' data > Write for BorrowedCursor < ' buf , ' data > {
297+ impl < ' a > Write for BorrowedCursor < ' a > {
279298 fn write ( & mut self , buf : & [ u8 ] ) -> Result < usize > {
280299 self . append ( buf) ;
281300 Ok ( buf. len ( ) )
0 commit comments