Use ManuallyDrop in BufWriter::into_parts
This commit is contained in:
parent
5d76a13bbe
commit
7fc69436a1
@ -3,7 +3,7 @@
|
|||||||
use crate::io::{
|
use crate::io::{
|
||||||
self, ErrorKind, IntoInnerError, IoSlice, Seek, SeekFrom, Write, DEFAULT_BUF_SIZE,
|
self, ErrorKind, IntoInnerError, IoSlice, Seek, SeekFrom, Write, DEFAULT_BUF_SIZE,
|
||||||
};
|
};
|
||||||
use crate::mem;
|
use crate::mem::{self, ManuallyDrop};
|
||||||
use crate::ptr;
|
use crate::ptr;
|
||||||
|
|
||||||
/// Wraps a writer and buffers its output.
|
/// Wraps a writer and buffers its output.
|
||||||
@ -164,13 +164,13 @@ pub fn into_inner(mut self) -> Result<W, IntoInnerError<BufWriter<W>>> {
|
|||||||
/// assert_eq!(&buffered_data.unwrap(), b"ata");
|
/// assert_eq!(&buffered_data.unwrap(), b"ata");
|
||||||
/// ```
|
/// ```
|
||||||
#[stable(feature = "bufwriter_into_parts", since = "1.56.0")]
|
#[stable(feature = "bufwriter_into_parts", since = "1.56.0")]
|
||||||
pub fn into_parts(mut self) -> (W, Result<Vec<u8>, WriterPanicked>) {
|
pub fn into_parts(self) -> (W, Result<Vec<u8>, WriterPanicked>) {
|
||||||
let buf = mem::take(&mut self.buf);
|
let mut this = ManuallyDrop::new(self);
|
||||||
let buf = if !self.panicked { Ok(buf) } else { Err(WriterPanicked { buf }) };
|
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
|
// SAFETY: double-drops are prevented by putting `this` in a ManuallyDrop that is never dropped
|
||||||
let inner = unsafe { ptr::read(&self.inner) };
|
let inner = unsafe { ptr::read(&this.inner) };
|
||||||
mem::forget(self);
|
|
||||||
|
|
||||||
(inner, buf)
|
(inner, buf)
|
||||||
}
|
}
|
||||||
|
@ -1067,3 +1067,13 @@ fn read(&mut self, buf: &mut [u8]) -> crate::io::Result<usize> {
|
|||||||
// But we initialized the whole buffer!
|
// But we initialized the whole buffer!
|
||||||
assert_eq!(reader.initialized(), reader.capacity());
|
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();
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user