diff --git a/src/libstd/io/buffered.rs b/src/libstd/io/buffered.rs index a26a932ad2de6..0a8288c55ea5f 100644 --- a/src/libstd/io/buffered.rs +++ b/src/libstd/io/buffered.rs @@ -17,7 +17,9 @@ use cmp; use error; use fmt; use io::{self, DEFAULT_BUF_SIZE, Error, ErrorKind, SeekFrom}; +use mem; use memchr; +use ptr; /// The `BufReader` struct adds buffering to any reader. /// @@ -297,7 +299,7 @@ impl Seek for BufReader { /// the `stream` is dropped. #[stable(feature = "rust1", since = "1.0.0")] pub struct BufWriter { - inner: Option, + inner: W, buf: Vec, // #30888: If the inner writer panics in a call to write, we don't want to // write the buffered data a second time in BufWriter's destructor. This @@ -365,7 +367,7 @@ impl BufWriter { #[stable(feature = "rust1", since = "1.0.0")] pub fn with_capacity(cap: usize, inner: W) -> BufWriter { BufWriter { - inner: Some(inner), + inner: inner, buf: Vec::with_capacity(cap), panicked: false, } @@ -377,7 +379,7 @@ impl BufWriter { let mut ret = Ok(()); while written < len { self.panicked = true; - let r = self.inner.as_mut().unwrap().write(&self.buf[written..]); + let r = self.inner.write(&self.buf[written..]); self.panicked = false; match r { @@ -412,7 +414,7 @@ impl BufWriter { /// let reference = buffer.get_ref(); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - pub fn get_ref(&self) -> &W { self.inner.as_ref().unwrap() } + pub fn get_ref(&self) -> &W { &self.inner } /// Gets a mutable reference to the underlying writer. /// @@ -430,7 +432,7 @@ impl BufWriter { /// let reference = buffer.get_mut(); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - pub fn get_mut(&mut self) -> &mut W { self.inner.as_mut().unwrap() } + pub fn get_mut(&mut self) -> &mut W { &mut self.inner } /// Unwraps this `BufWriter`, returning the underlying writer. /// @@ -451,7 +453,14 @@ impl BufWriter { pub fn into_inner(mut self) -> Result>> { match self.flush_buf() { Err(e) => Err(IntoInnerError(self, e)), - Ok(()) => Ok(self.inner.take().unwrap()) + Ok(()) => unsafe { + // use `ptr::read` to extract the inner writer and circumvent + // our `Drop` implementation + mem::replace(&mut self.buf, Vec::new()); + let inner = ptr::read(&self.inner); + mem::forget(self); + Ok(inner) + }, } } } @@ -464,7 +473,7 @@ impl Write for BufWriter { } if buf.len() >= self.buf.capacity() { self.panicked = true; - let r = self.inner.as_mut().unwrap().write(buf); + let r = self.inner.write(buf); self.panicked = false; r } else { @@ -481,7 +490,7 @@ impl Write for BufWriter { impl fmt::Debug for BufWriter where W: fmt::Debug { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { fmt.debug_struct("BufWriter") - .field("writer", &self.inner.as_ref().unwrap()) + .field("writer", &self.inner) .field("buffer", &format_args!("{}/{}", self.buf.len(), self.buf.capacity())) .finish() } @@ -500,7 +509,7 @@ impl Seek for BufWriter { #[stable(feature = "rust1", since = "1.0.0")] impl Drop for BufWriter { fn drop(&mut self) { - if self.inner.is_some() && !self.panicked { + if !self.panicked { // dtors should not panic, so we ignore a failed flush let _r = self.flush_buf(); }