Skip to content

Commit 6f35180

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 6f35180

1 file changed

Lines changed: 8 additions & 1 deletion

File tree

library/std/src/io/copy.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,9 @@ impl<I: Write + ?Sized> BufferedWriterSpec for BufWriter<I> {
221221
let mut read_buf: BorrowedBuf<'_> = buf.spare_capacity_mut().into();
222222

223223
if init {
224-
// SAFETY: init is either 0 or the init_len from the previous iteration.
224+
// SAFETY: `init` is only true after `reader` initializes `read_buf`,
225+
// and is reset after each `flush_buf` in case `flush_buf` caused a
226+
// re-allocation or any other kind of de-initialization.
225227
unsafe { read_buf.set_init() };
226228
}
227229

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

0 commit comments

Comments
 (0)