Skip to content

Commit

Permalink
Use ManuallyDrop in BufWriter::into_parts
Browse files Browse the repository at this point in the history
  • Loading branch information
saethlin committed Jul 12, 2024
1 parent 5d76a13 commit f07f337
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 6 deletions.
12 changes: 6 additions & 6 deletions library/std/src/io/buffered/bufwriter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use crate::fmt;
use crate::io::{
self, ErrorKind, IntoInnerError, IoSlice, Seek, SeekFrom, Write, DEFAULT_BUF_SIZE,
};
use crate::mem;
use crate::mem::{self, ManuallyDrop};
use crate::ptr;

/// Wraps a writer and buffers its output.
Expand Down Expand Up @@ -164,13 +164,13 @@ impl<W: Write> BufWriter<W> {
/// assert_eq!(&buffered_data.unwrap(), b"ata");
/// ```
#[stable(feature = "bufwriter_into_parts", since = "1.56.0")]
pub fn into_parts(mut self) -> (W, Result<Vec<u8>, WriterPanicked>) {
let buf = mem::take(&mut self.buf);
let buf = if !self.panicked { Ok(buf) } else { Err(WriterPanicked { buf }) };
pub fn into_parts(self) -> (W, Result<Vec<u8>, WriterPanicked>) {
let mut this = ManuallyDrop::new(self);
let buf = mem::take(&mut this.buf);
let buf = if !this.panicked { Ok(buf) } else { Err(WriterPanicked { buf }) };

// SAFETY: forget(self) prevents double dropping inner
let inner = unsafe { ptr::read(&self.inner) };
mem::forget(self);
let inner = unsafe { ptr::read(&this.inner) };

(inner, buf)
}
Expand Down
10 changes: 10 additions & 0 deletions library/std/src/io/buffered/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1067,3 +1067,13 @@ fn bufreader_full_initialize() {
// But we initialized the whole buffer!
assert_eq!(reader.initialized(), reader.capacity());
}

/// This is a regression test for https://github.com/rust-lang/rust/issues/127584.
#[test]
fn bufwriter_aliasing() {
use crate::io::{BufWriter, Cursor};
let mut v = vec![0; 1024];
let c = Cursor::new(&mut v);
let w = BufWriter::new(Box::new(c));
let _ = w.into_parts();
}

0 comments on commit f07f337

Please sign in to comment.