Rollup merge of #111074 - WaffleLapkin:🌟unsizes_your_buf_reader🌟, r=Amanieu
Relax implicit `T: Sized` bounds on `BufReader<T>`, `BufWriter<T>` and `LineWriter<T>` TL;DR: ```diff,rust -pub struct BufReader<R> { /* ... */ } +pub struct BufReader<R: ?Sized> { /* ... */ } -pub struct BufWriter<W: Write> { /* ... */ } +pub struct BufWriter<W: ?Sized + Write> { /* ... */ } -pub struct LineWriter<W: Write> { /* ... */ } +pub struct LineWriter<W: ?Sized + Write> { /* ... */ } ``` This allows using `&mut BufReader<dyn Read>`, for example. **This is an insta-stable change**.
This commit is contained in:
commit
c55af41e7a
7 changed files with 118 additions and 111 deletions
|
@ -47,9 +47,9 @@ use buffer::Buffer;
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
pub struct BufReader<R> {
|
pub struct BufReader<R: ?Sized> {
|
||||||
inner: R,
|
|
||||||
buf: Buffer,
|
buf: Buffer,
|
||||||
|
inner: R,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<R: Read> BufReader<R> {
|
impl<R: Read> BufReader<R> {
|
||||||
|
@ -95,7 +95,7 @@ impl<R: Read> BufReader<R> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<R> BufReader<R> {
|
impl<R: ?Sized> BufReader<R> {
|
||||||
/// Gets a reference to the underlying reader.
|
/// Gets a reference to the underlying reader.
|
||||||
///
|
///
|
||||||
/// It is inadvisable to directly read from the underlying reader.
|
/// It is inadvisable to directly read from the underlying reader.
|
||||||
|
@ -213,7 +213,10 @@ impl<R> BufReader<R> {
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
pub fn into_inner(self) -> R {
|
pub fn into_inner(self) -> R
|
||||||
|
where
|
||||||
|
R: Sized,
|
||||||
|
{
|
||||||
self.inner
|
self.inner
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -226,13 +229,13 @@ impl<R> BufReader<R> {
|
||||||
|
|
||||||
// This is only used by a test which asserts that the initialization-tracking is correct.
|
// This is only used by a test which asserts that the initialization-tracking is correct.
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
impl<R> BufReader<R> {
|
impl<R: ?Sized> BufReader<R> {
|
||||||
pub fn initialized(&self) -> usize {
|
pub fn initialized(&self) -> usize {
|
||||||
self.buf.initialized()
|
self.buf.initialized()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<R: Seek> BufReader<R> {
|
impl<R: ?Sized + Seek> BufReader<R> {
|
||||||
/// Seeks relative to the current position. If the new position lies within the buffer,
|
/// Seeks relative to the current position. If the new position lies within the buffer,
|
||||||
/// the buffer will not be flushed, allowing for more efficient seeks.
|
/// the buffer will not be flushed, allowing for more efficient seeks.
|
||||||
/// This method does not return the location of the underlying reader, so the caller
|
/// This method does not return the location of the underlying reader, so the caller
|
||||||
|
@ -257,7 +260,7 @@ impl<R: Seek> BufReader<R> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
impl<R: Read> Read for BufReader<R> {
|
impl<R: ?Sized + Read> Read for BufReader<R> {
|
||||||
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
||||||
// If we don't have any buffered data and we're doing a massive read
|
// If we don't have any buffered data and we're doing a massive read
|
||||||
// (larger than our internal buffer), bypass our internal buffer
|
// (larger than our internal buffer), bypass our internal buffer
|
||||||
|
@ -371,7 +374,7 @@ impl<R: Read> Read for BufReader<R> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
impl<R: Read> BufRead for BufReader<R> {
|
impl<R: ?Sized + Read> BufRead for BufReader<R> {
|
||||||
fn fill_buf(&mut self) -> io::Result<&[u8]> {
|
fn fill_buf(&mut self) -> io::Result<&[u8]> {
|
||||||
self.buf.fill_buf(&mut self.inner)
|
self.buf.fill_buf(&mut self.inner)
|
||||||
}
|
}
|
||||||
|
@ -384,11 +387,11 @@ impl<R: Read> BufRead for BufReader<R> {
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
impl<R> fmt::Debug for BufReader<R>
|
impl<R> fmt::Debug for BufReader<R>
|
||||||
where
|
where
|
||||||
R: fmt::Debug,
|
R: ?Sized + fmt::Debug,
|
||||||
{
|
{
|
||||||
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
fmt.debug_struct("BufReader")
|
fmt.debug_struct("BufReader")
|
||||||
.field("reader", &self.inner)
|
.field("reader", &&self.inner)
|
||||||
.field(
|
.field(
|
||||||
"buffer",
|
"buffer",
|
||||||
&format_args!("{}/{}", self.buf.filled() - self.buf.pos(), self.capacity()),
|
&format_args!("{}/{}", self.buf.filled() - self.buf.pos(), self.capacity()),
|
||||||
|
@ -398,7 +401,7 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
impl<R: Seek> Seek for BufReader<R> {
|
impl<R: ?Sized + Seek> Seek for BufReader<R> {
|
||||||
/// Seek to an offset, in bytes, in the underlying reader.
|
/// Seek to an offset, in bytes, in the underlying reader.
|
||||||
///
|
///
|
||||||
/// The position used for seeking with <code>[SeekFrom::Current]\(_)</code> is the
|
/// The position used for seeking with <code>[SeekFrom::Current]\(_)</code> is the
|
||||||
|
@ -491,7 +494,7 @@ impl<R: Seek> Seek for BufReader<R> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> SizeHint for BufReader<T> {
|
impl<T: ?Sized> SizeHint for BufReader<T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn lower_bound(&self) -> usize {
|
fn lower_bound(&self) -> usize {
|
||||||
SizeHint::lower_bound(self.get_ref()) + self.buffer().len()
|
SizeHint::lower_bound(self.get_ref()) + self.buffer().len()
|
||||||
|
|
|
@ -67,8 +67,7 @@ use crate::ptr;
|
||||||
/// [`TcpStream`]: crate::net::TcpStream
|
/// [`TcpStream`]: crate::net::TcpStream
|
||||||
/// [`flush`]: BufWriter::flush
|
/// [`flush`]: BufWriter::flush
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
pub struct BufWriter<W: Write> {
|
pub struct BufWriter<W: ?Sized + Write> {
|
||||||
inner: W,
|
|
||||||
// The buffer. Avoid using this like a normal `Vec` in common code paths.
|
// The buffer. Avoid using this like a normal `Vec` in common code paths.
|
||||||
// That is, don't use `buf.push`, `buf.extend_from_slice`, or any other
|
// That is, don't use `buf.push`, `buf.extend_from_slice`, or any other
|
||||||
// methods that require bounds checking or the like. This makes an enormous
|
// methods that require bounds checking or the like. This makes an enormous
|
||||||
|
@ -78,6 +77,7 @@ pub struct BufWriter<W: Write> {
|
||||||
// write the buffered data a second time in BufWriter's destructor. This
|
// write the buffered data a second time in BufWriter's destructor. This
|
||||||
// flag tells the Drop impl if it should skip the flush.
|
// flag tells the Drop impl if it should skip the flush.
|
||||||
panicked: bool,
|
panicked: bool,
|
||||||
|
inner: W,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<W: Write> BufWriter<W> {
|
impl<W: Write> BufWriter<W> {
|
||||||
|
@ -115,6 +115,69 @@ impl<W: Write> BufWriter<W> {
|
||||||
BufWriter { inner, buf: Vec::with_capacity(capacity), panicked: false }
|
BufWriter { inner, buf: Vec::with_capacity(capacity), panicked: false }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Unwraps this `BufWriter<W>`, returning the underlying writer.
|
||||||
|
///
|
||||||
|
/// The buffer is written out before returning the writer.
|
||||||
|
///
|
||||||
|
/// # Errors
|
||||||
|
///
|
||||||
|
/// An [`Err`] will be returned if an error occurs while flushing the buffer.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```no_run
|
||||||
|
/// use std::io::BufWriter;
|
||||||
|
/// use std::net::TcpStream;
|
||||||
|
///
|
||||||
|
/// let mut buffer = BufWriter::new(TcpStream::connect("127.0.0.1:34254").unwrap());
|
||||||
|
///
|
||||||
|
/// // unwrap the TcpStream and flush the buffer
|
||||||
|
/// let stream = buffer.into_inner().unwrap();
|
||||||
|
/// ```
|
||||||
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
pub fn into_inner(mut self) -> Result<W, IntoInnerError<BufWriter<W>>> {
|
||||||
|
match self.flush_buf() {
|
||||||
|
Err(e) => Err(IntoInnerError::new(self, e)),
|
||||||
|
Ok(()) => Ok(self.into_parts().0),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Disassembles this `BufWriter<W>`, returning the underlying writer, and any buffered but
|
||||||
|
/// unwritten data.
|
||||||
|
///
|
||||||
|
/// If the underlying writer panicked, it is not known what portion of the data was written.
|
||||||
|
/// In this case, we return `WriterPanicked` for the buffered data (from which the buffer
|
||||||
|
/// contents can still be recovered).
|
||||||
|
///
|
||||||
|
/// `into_parts` makes no attempt to flush data and cannot fail.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use std::io::{BufWriter, Write};
|
||||||
|
///
|
||||||
|
/// let mut buffer = [0u8; 10];
|
||||||
|
/// let mut stream = BufWriter::new(buffer.as_mut());
|
||||||
|
/// write!(stream, "too much data").unwrap();
|
||||||
|
/// stream.flush().expect_err("it doesn't fit");
|
||||||
|
/// let (recovered_writer, buffered_data) = stream.into_parts();
|
||||||
|
/// assert_eq!(recovered_writer.len(), 0);
|
||||||
|
/// 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 }) };
|
||||||
|
|
||||||
|
// SAFETY: forget(self) prevents double dropping inner
|
||||||
|
let inner = unsafe { ptr::read(&self.inner) };
|
||||||
|
mem::forget(self);
|
||||||
|
|
||||||
|
(inner, buf)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<W: ?Sized + Write> BufWriter<W> {
|
||||||
/// Send data in our local buffer into the inner writer, looping as
|
/// Send data in our local buffer into the inner writer, looping as
|
||||||
/// necessary until either it's all been sent or an error occurs.
|
/// necessary until either it's all been sent or an error occurs.
|
||||||
///
|
///
|
||||||
|
@ -284,67 +347,6 @@ impl<W: Write> BufWriter<W> {
|
||||||
self.buf.capacity()
|
self.buf.capacity()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Unwraps this `BufWriter<W>`, returning the underlying writer.
|
|
||||||
///
|
|
||||||
/// The buffer is written out before returning the writer.
|
|
||||||
///
|
|
||||||
/// # Errors
|
|
||||||
///
|
|
||||||
/// An [`Err`] will be returned if an error occurs while flushing the buffer.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```no_run
|
|
||||||
/// use std::io::BufWriter;
|
|
||||||
/// use std::net::TcpStream;
|
|
||||||
///
|
|
||||||
/// let mut buffer = BufWriter::new(TcpStream::connect("127.0.0.1:34254").unwrap());
|
|
||||||
///
|
|
||||||
/// // unwrap the TcpStream and flush the buffer
|
|
||||||
/// let stream = buffer.into_inner().unwrap();
|
|
||||||
/// ```
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
|
||||||
pub fn into_inner(mut self) -> Result<W, IntoInnerError<BufWriter<W>>> {
|
|
||||||
match self.flush_buf() {
|
|
||||||
Err(e) => Err(IntoInnerError::new(self, e)),
|
|
||||||
Ok(()) => Ok(self.into_parts().0),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Disassembles this `BufWriter<W>`, returning the underlying writer, and any buffered but
|
|
||||||
/// unwritten data.
|
|
||||||
///
|
|
||||||
/// If the underlying writer panicked, it is not known what portion of the data was written.
|
|
||||||
/// In this case, we return `WriterPanicked` for the buffered data (from which the buffer
|
|
||||||
/// contents can still be recovered).
|
|
||||||
///
|
|
||||||
/// `into_parts` makes no attempt to flush data and cannot fail.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// use std::io::{BufWriter, Write};
|
|
||||||
///
|
|
||||||
/// let mut buffer = [0u8; 10];
|
|
||||||
/// let mut stream = BufWriter::new(buffer.as_mut());
|
|
||||||
/// write!(stream, "too much data").unwrap();
|
|
||||||
/// stream.flush().expect_err("it doesn't fit");
|
|
||||||
/// let (recovered_writer, buffered_data) = stream.into_parts();
|
|
||||||
/// assert_eq!(recovered_writer.len(), 0);
|
|
||||||
/// 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 }) };
|
|
||||||
|
|
||||||
// SAFETY: forget(self) prevents double dropping inner
|
|
||||||
let inner = unsafe { ptr::read(&self.inner) };
|
|
||||||
mem::forget(self);
|
|
||||||
|
|
||||||
(inner, buf)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ensure this function does not get inlined into `write`, so that it
|
// Ensure this function does not get inlined into `write`, so that it
|
||||||
// remains inlineable and its common path remains as short as possible.
|
// remains inlineable and its common path remains as short as possible.
|
||||||
// If this function ends up being called frequently relative to `write`,
|
// If this function ends up being called frequently relative to `write`,
|
||||||
|
@ -511,7 +513,7 @@ impl fmt::Debug for WriterPanicked {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
impl<W: Write> Write for BufWriter<W> {
|
impl<W: ?Sized + Write> Write for BufWriter<W> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
||||||
// Use < instead of <= to avoid a needless trip through the buffer in some cases.
|
// Use < instead of <= to avoid a needless trip through the buffer in some cases.
|
||||||
|
@ -640,20 +642,20 @@ impl<W: Write> Write for BufWriter<W> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
impl<W: Write> fmt::Debug for BufWriter<W>
|
impl<W: ?Sized + Write> fmt::Debug for BufWriter<W>
|
||||||
where
|
where
|
||||||
W: fmt::Debug,
|
W: fmt::Debug,
|
||||||
{
|
{
|
||||||
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
fmt.debug_struct("BufWriter")
|
fmt.debug_struct("BufWriter")
|
||||||
.field("writer", &self.inner)
|
.field("writer", &&self.inner)
|
||||||
.field("buffer", &format_args!("{}/{}", self.buf.len(), self.buf.capacity()))
|
.field("buffer", &format_args!("{}/{}", self.buf.len(), self.buf.capacity()))
|
||||||
.finish()
|
.finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
impl<W: Write + Seek> Seek for BufWriter<W> {
|
impl<W: ?Sized + Write + Seek> Seek for BufWriter<W> {
|
||||||
/// Seek to the offset, in bytes, in the underlying writer.
|
/// Seek to the offset, in bytes, in the underlying writer.
|
||||||
///
|
///
|
||||||
/// Seeking always writes out the internal buffer before seeking.
|
/// Seeking always writes out the internal buffer before seeking.
|
||||||
|
@ -664,7 +666,7 @@ impl<W: Write + Seek> Seek for BufWriter<W> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
impl<W: Write> Drop for BufWriter<W> {
|
impl<W: ?Sized + Write> Drop for BufWriter<W> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
if !self.panicked {
|
if !self.panicked {
|
||||||
// dtors should not panic, so we ignore a failed flush
|
// dtors should not panic, so we ignore a failed flush
|
||||||
|
|
|
@ -64,7 +64,7 @@ use crate::io::{self, buffered::LineWriterShim, BufWriter, IntoInnerError, IoSli
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
pub struct LineWriter<W: Write> {
|
pub struct LineWriter<W: ?Sized + Write> {
|
||||||
inner: BufWriter<W>,
|
inner: BufWriter<W>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -109,27 +109,6 @@ impl<W: Write> LineWriter<W> {
|
||||||
LineWriter { inner: BufWriter::with_capacity(capacity, inner) }
|
LineWriter { inner: BufWriter::with_capacity(capacity, inner) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets a reference to the underlying writer.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```no_run
|
|
||||||
/// use std::fs::File;
|
|
||||||
/// use std::io::LineWriter;
|
|
||||||
///
|
|
||||||
/// fn main() -> std::io::Result<()> {
|
|
||||||
/// let file = File::create("poem.txt")?;
|
|
||||||
/// let file = LineWriter::new(file);
|
|
||||||
///
|
|
||||||
/// let reference = file.get_ref();
|
|
||||||
/// Ok(())
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
|
||||||
pub fn get_ref(&self) -> &W {
|
|
||||||
self.inner.get_ref()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Gets a mutable reference to the underlying writer.
|
/// Gets a mutable reference to the underlying writer.
|
||||||
///
|
///
|
||||||
/// Caution must be taken when calling methods on the mutable reference
|
/// Caution must be taken when calling methods on the mutable reference
|
||||||
|
@ -184,8 +163,31 @@ impl<W: Write> LineWriter<W> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<W: ?Sized + Write> LineWriter<W> {
|
||||||
|
/// Gets a reference to the underlying writer.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```no_run
|
||||||
|
/// use std::fs::File;
|
||||||
|
/// use std::io::LineWriter;
|
||||||
|
///
|
||||||
|
/// fn main() -> std::io::Result<()> {
|
||||||
|
/// let file = File::create("poem.txt")?;
|
||||||
|
/// let file = LineWriter::new(file);
|
||||||
|
///
|
||||||
|
/// let reference = file.get_ref();
|
||||||
|
/// Ok(())
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
|
pub fn get_ref(&self) -> &W {
|
||||||
|
self.inner.get_ref()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
impl<W: Write> Write for LineWriter<W> {
|
impl<W: ?Sized + Write> Write for LineWriter<W> {
|
||||||
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
||||||
LineWriterShim::new(&mut self.inner).write(buf)
|
LineWriterShim::new(&mut self.inner).write(buf)
|
||||||
}
|
}
|
||||||
|
@ -216,7 +218,7 @@ impl<W: Write> Write for LineWriter<W> {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
impl<W: Write> fmt::Debug for LineWriter<W>
|
impl<W: ?Sized + Write> fmt::Debug for LineWriter<W>
|
||||||
where
|
where
|
||||||
W: fmt::Debug,
|
W: fmt::Debug,
|
||||||
{
|
{
|
||||||
|
|
|
@ -11,11 +11,11 @@ use crate::sys_common::memchr;
|
||||||
/// `BufWriters` to be temporarily given line-buffering logic; this is what
|
/// `BufWriters` to be temporarily given line-buffering logic; this is what
|
||||||
/// enables Stdout to be alternately in line-buffered or block-buffered mode.
|
/// enables Stdout to be alternately in line-buffered or block-buffered mode.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct LineWriterShim<'a, W: Write> {
|
pub struct LineWriterShim<'a, W: ?Sized + Write> {
|
||||||
buffer: &'a mut BufWriter<W>,
|
buffer: &'a mut BufWriter<W>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, W: Write> LineWriterShim<'a, W> {
|
impl<'a, W: ?Sized + Write> LineWriterShim<'a, W> {
|
||||||
pub fn new(buffer: &'a mut BufWriter<W>) -> Self {
|
pub fn new(buffer: &'a mut BufWriter<W>) -> Self {
|
||||||
Self { buffer }
|
Self { buffer }
|
||||||
}
|
}
|
||||||
|
@ -49,7 +49,7 @@ impl<'a, W: Write> LineWriterShim<'a, W> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, W: Write> Write for LineWriterShim<'a, W> {
|
impl<'a, W: ?Sized + Write> Write for LineWriterShim<'a, W> {
|
||||||
/// Write some data into this BufReader with line buffering. This means
|
/// Write some data into this BufReader with line buffering. This means
|
||||||
/// that, if any newlines are present in the data, the data up to the last
|
/// that, if any newlines are present in the data, the data up to the last
|
||||||
/// newline is sent directly to the underlying writer, and data after it
|
/// newline is sent directly to the underlying writer, and data after it
|
||||||
|
|
|
@ -86,7 +86,7 @@ impl<W: Write + ?Sized> BufferedCopySpec for W {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I: Write> BufferedCopySpec for BufWriter<I> {
|
impl<I: ?Sized + Write> BufferedCopySpec for BufWriter<I> {
|
||||||
fn copy_to<R: Read + ?Sized>(reader: &mut R, writer: &mut Self) -> Result<u64> {
|
fn copy_to<R: Read + ?Sized>(reader: &mut R, writer: &mut Self) -> Result<u64> {
|
||||||
if writer.capacity() < DEFAULT_BUF_SIZE {
|
if writer.capacity() < DEFAULT_BUF_SIZE {
|
||||||
return stack_buffer_copy(reader, writer);
|
return stack_buffer_copy(reader, writer);
|
||||||
|
|
|
@ -2754,7 +2754,7 @@ trait SizeHint {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> SizeHint for T {
|
impl<T: ?Sized> SizeHint for T {
|
||||||
#[inline]
|
#[inline]
|
||||||
default fn lower_bound(&self) -> usize {
|
default fn lower_bound(&self) -> usize {
|
||||||
0
|
0
|
||||||
|
|
|
@ -466,7 +466,7 @@ impl<T: CopyRead> CopyRead for Take<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: CopyRead> CopyRead for BufReader<T> {
|
impl<T: ?Sized + CopyRead> CopyRead for BufReader<T> {
|
||||||
fn drain_to<W: Write>(&mut self, writer: &mut W, outer_limit: u64) -> Result<u64> {
|
fn drain_to<W: Write>(&mut self, writer: &mut W, outer_limit: u64) -> Result<u64> {
|
||||||
let buf = self.buffer();
|
let buf = self.buffer();
|
||||||
let buf = &buf[0..min(buf.len(), outer_limit.try_into().unwrap_or(usize::MAX))];
|
let buf = &buf[0..min(buf.len(), outer_limit.try_into().unwrap_or(usize::MAX))];
|
||||||
|
@ -495,7 +495,7 @@ impl<T: CopyRead> CopyRead for BufReader<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: CopyWrite> CopyWrite for BufWriter<T> {
|
impl<T: ?Sized + CopyWrite> CopyWrite for BufWriter<T> {
|
||||||
fn properties(&self) -> CopyParams {
|
fn properties(&self) -> CopyParams {
|
||||||
self.get_ref().properties()
|
self.get_ref().properties()
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue