Skip to content

Commit bf1a8da

Browse files
committed
Make std::io::copy take Read and Write by value instead of by reference
The traits are also implemented on mutable references of types implementing that trait.
1 parent f557a4f commit bf1a8da

File tree

2 files changed

+24
-24
lines changed

2 files changed

+24
-24
lines changed

library/std/src/io/copy.rs

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ use crate::mem::MaybeUninit;
5050
///
5151
/// [changes]: crate::io#platform-specific-behavior
5252
#[stable(feature = "rust1", since = "1.0.0")]
53-
pub fn copy<R: ?Sized, W: ?Sized>(reader: &mut R, writer: &mut W) -> Result<u64>
53+
pub fn copy<R, W>(reader: R, writer: W) -> Result<u64>
5454
where
5555
R: Read,
5656
W: Write,
@@ -66,7 +66,7 @@ where
6666

6767
/// The userspace read-write-loop implementation of `io::copy` that is used when
6868
/// OS-specific specializations for copy offloading are not available or not applicable.
69-
pub(crate) fn generic_copy<R: ?Sized, W: ?Sized>(reader: &mut R, writer: &mut W) -> Result<u64>
69+
pub(crate) fn generic_copy<R, W>(reader: R, writer: W) -> Result<u64>
7070
where
7171
R: Read,
7272
W: Write,
@@ -77,17 +77,23 @@ where
7777
/// Specialization of the read-write loop that either uses a stack buffer
7878
/// or reuses the internal buffer of a BufWriter
7979
trait BufferedCopySpec: Write {
80-
fn copy_to<R: Read + ?Sized>(reader: &mut R, writer: &mut Self) -> Result<u64>;
80+
fn copy_to<R: Read>(reader: R, writer: Self) -> Result<u64>;
8181
}
8282

83-
impl<W: Write + ?Sized> BufferedCopySpec for W {
84-
default fn copy_to<R: Read + ?Sized>(reader: &mut R, writer: &mut Self) -> Result<u64> {
83+
impl<W: Write> BufferedCopySpec for W {
84+
default fn copy_to<R: Read>(reader: R, writer: Self) -> Result<u64> {
8585
stack_buffer_copy(reader, writer)
8686
}
8787
}
8888

8989
impl<I: Write> BufferedCopySpec for BufWriter<I> {
90-
fn copy_to<R: Read + ?Sized>(reader: &mut R, writer: &mut Self) -> Result<u64> {
90+
fn copy_to<R: Read>(reader: R, mut writer: Self) -> Result<u64> {
91+
BufferedCopySpec::copy_to(reader, &mut writer)
92+
}
93+
}
94+
95+
impl<I: Write> BufferedCopySpec for &mut BufWriter<I> {
96+
fn copy_to<R: Read>(mut reader: R, writer: Self) -> Result<u64> {
9197
if writer.capacity() < DEFAULT_BUF_SIZE {
9298
return stack_buffer_copy(reader, writer);
9399
}
@@ -134,10 +140,7 @@ impl<I: Write> BufferedCopySpec for BufWriter<I> {
134140
}
135141
}
136142

137-
fn stack_buffer_copy<R: Read + ?Sized, W: Write + ?Sized>(
138-
reader: &mut R,
139-
writer: &mut W,
140-
) -> Result<u64> {
143+
fn stack_buffer_copy<R: Read, W: Write>(mut reader: R, mut writer: W) -> Result<u64> {
141144
let buf: &mut [_] = &mut [MaybeUninit::uninit(); DEFAULT_BUF_SIZE];
142145
let mut buf: BorrowedBuf<'_> = buf.into();
143146

library/std/src/sys/unix/kernel_copy.rs

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,7 @@ use libc::{EBADF, EINVAL, ENOSYS, EOPNOTSUPP, EOVERFLOW, EPERM, EXDEV};
6868
#[cfg(test)]
6969
mod tests;
7070

71-
pub(crate) fn copy_spec<R: Read + ?Sized, W: Write + ?Sized>(
72-
read: &mut R,
73-
write: &mut W,
74-
) -> Result<u64> {
71+
pub(crate) fn copy_spec<R: Read, W: Write>(read: R, write: W) -> Result<u64> {
7572
let copier = Copier { read, write };
7673
SpecCopy::copy(copier)
7774
}
@@ -160,30 +157,30 @@ fn safe_kernel_copy(source: &FdMeta, sink: &FdMeta) -> bool {
160157

161158
struct CopyParams(FdMeta, Option<RawFd>);
162159

163-
struct Copier<'a, 'b, R: Read + ?Sized, W: Write + ?Sized> {
164-
read: &'a mut R,
165-
write: &'b mut W,
160+
struct Copier<R: Read, W: Write> {
161+
read: R,
162+
write: W,
166163
}
167164

168165
trait SpecCopy {
169166
fn copy(self) -> Result<u64>;
170167
}
171168

172-
impl<R: Read + ?Sized, W: Write + ?Sized> SpecCopy for Copier<'_, '_, R, W> {
169+
impl<R: Read, W: Write> SpecCopy for Copier<R, W> {
173170
default fn copy(self) -> Result<u64> {
174171
generic_copy(self.read, self.write)
175172
}
176173
}
177174

178-
impl<R: CopyRead, W: CopyWrite> SpecCopy for Copier<'_, '_, R, W> {
175+
impl<R: CopyRead, W: CopyWrite> SpecCopy for Copier<R, W> {
179176
fn copy(self) -> Result<u64> {
180-
let (reader, writer) = (self.read, self.write);
177+
let Copier { read: mut reader, write: mut writer } = self;
181178
let r_cfg = reader.properties();
182179
let w_cfg = writer.properties();
183180

184181
// before direct operations on file descriptors ensure that all source and sink buffers are empty
185182
let mut flush = || -> crate::io::Result<u64> {
186-
let bytes = reader.drain_to(writer, u64::MAX)?;
183+
let bytes = reader.drain_to(&mut writer, u64::MAX)?;
187184
// BufWriter buffered bytes have already been accounted for in earlier write() calls
188185
writer.flush()?;
189186
Ok(bytes)
@@ -199,7 +196,7 @@ impl<R: CopyRead, W: CopyWrite> SpecCopy for Copier<'_, '_, R, W> {
199196

200197
if input_meta.copy_file_range_candidate() && output_meta.copy_file_range_candidate() {
201198
let result = copy_regular_files(readfd, writefd, max_write);
202-
result.update_take(reader);
199+
result.update_take(&mut reader);
203200

204201
match result {
205202
CopyResult::Ended(bytes_copied) => return Ok(bytes_copied + written),
@@ -216,7 +213,7 @@ impl<R: CopyRead, W: CopyWrite> SpecCopy for Copier<'_, '_, R, W> {
216213
if input_meta.potential_sendfile_source() && safe_kernel_copy(&input_meta, &output_meta)
217214
{
218215
let result = sendfile_splice(SpliceMode::Sendfile, readfd, writefd, max_write);
219-
result.update_take(reader);
216+
result.update_take(&mut reader);
220217

221218
match result {
222219
CopyResult::Ended(bytes_copied) => return Ok(bytes_copied + written),
@@ -229,7 +226,7 @@ impl<R: CopyRead, W: CopyWrite> SpecCopy for Copier<'_, '_, R, W> {
229226
&& safe_kernel_copy(&input_meta, &output_meta)
230227
{
231228
let result = sendfile_splice(SpliceMode::Splice, readfd, writefd, max_write);
232-
result.update_take(reader);
229+
result.update_take(&mut reader);
233230

234231
match result {
235232
CopyResult::Ended(bytes_copied) => return Ok(bytes_copied + written),

0 commit comments

Comments
 (0)