Skip to content

Commit 858db5d

Browse files
committed
BufWriter: Make the soundness of BorrowedBuf usage clearer.
The previous safety comment was outdated as it was written before `BorrowedBuf::set_init` was changed to be a boolean. It also failed to address the possibility that `flush_buf` invalidated the assumption.
1 parent 12f35ad commit 858db5d

1 file changed

Lines changed: 8 additions & 2 deletions

File tree

library/std/src/io/copy.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -219,9 +219,10 @@ impl<I: Write + ?Sized> BufferedWriterSpec for BufWriter<I> {
219219
loop {
220220
let buf = self.buffer_mut();
221221
let mut read_buf: BorrowedBuf<'_> = buf.spare_capacity_mut().into();
222-
223222
if init {
224-
// SAFETY: init is either 0 or the init_len from the previous iteration.
223+
// SAFETY: `init` is only true after `reader` initializes `read_buf`,
224+
// and is reset after each `flush_buf` in case `flush_buf` caused a
225+
// re-allocation or any other kind of de-initialization.
225226
unsafe { read_buf.set_init() };
226227
}
227228

@@ -249,6 +250,11 @@ impl<I: Write + ?Sized> BufferedWriterSpec for BufWriter<I> {
249250
}
250251
} else {
251252
self.flush_buf()?;
253+
// A less conservative alternative, if this causes performance issues, would be to
254+
// enhance `flush_buf` to guarantee that it doesn't cause `self.buf` to reallocate
255+
// or to de-initialize its spare capacity. (That may be possible as `flush_buf`
256+
// never grows the buffer.)
257+
init = false;
252258
}
253259
}
254260
}

0 commit comments

Comments
 (0)