Skip to content

Commit 2f20b86

Browse files
committed
BufWriter: Note non-obvious safety assumption in BorrowedBuf::set_init usage.
1 parent 12f35ad commit 2f20b86

2 files changed

Lines changed: 10 additions & 2 deletions

File tree

library/std/src/io/buffered/bufwriter.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,12 @@ impl<W: ?Sized + Write> BufWriter<W> {
193193
/// `write`), any 0-length writes from `inner` must be reported as i/o
194194
/// errors from this method.
195195
pub(in crate::io) fn flush_buf(&mut self) -> io::Result<()> {
196+
// SAFETY: `<BufWriter as BufferedWriterSpec>::copy_from` requires that `self.buf`'s spare
197+
// capacity is preserved. This function does not grow `self.buf` or explicitly shrink its
198+
// capacity; `Vec` guarantees that this is sufficient to avoid it re-allocating. We never
199+
// de-initialize the spare capacity of `self.buf` and we assume none of the `Vec` methods
200+
// used here will do so either.
201+
196202
/// Helper struct to ensure the buffer is updated after all the writes
197203
/// are complete. It tracks the number of written bytes and drains them
198204
/// all from the front of the buffer when dropped.

library/std/src/io/copy.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -219,9 +219,11 @@ 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`. `flush_buf`
224+
// guarantees that it won't cause any part of the spare capacity to become
225+
// uninitialized or cause `self.buf` to reallocate, so it is OK to persist this
226+
// across `flush_buf` calls.
225227
unsafe { read_buf.set_init() };
226228
}
227229

0 commit comments

Comments
 (0)