Skip to content

Tracking issue for optional io::Read/io::Write methods #136756

Open
@thaliaarchi

Description

@thaliaarchi

This tracks the status of specializing optional methods in implementations of io::Read and io::Write in the standard library.

Read and Write have many methods which are provided by default, and many implementors do not override them, which can be problematic in some cases. Platform abstractions for stdio are particularly lacking; most of which do not have read_buf, so the buffer is forced to be initialized, and some platforms which support it might be missing vectored read/write. Since the standard library is general, this should be consistent.

I am working on addressing these gaps and have created this issue to track progress.

This surveys of all implementations of io::Read and io::Write in rust-lang/rust, including for private types, by searching for \b(Read|Write) for in .rs files. This should have no false negatives, as opposed to viewing references, which would omit other targets.

Additionally, I include all platform implementations of File. These define read, read_buf, read_vectored, is_read_vectored, write, write_vectored, is_write_vectored, and flush as inherent methods. Since the other methods are not currently supported with this scheme, I have marked them with N/A.

Implementation history

PRs created for this effort and some relevant PRs from earlier:

Read

pub trait Read {
    fn read(&mut self, buf: &mut [u8]) -> Result<usize>;
    fn read_buf(&mut self, buf: BorrowedCursor<'_>) -> Result<()> {}
    fn read_buf_exact(&mut self, buf: BorrowedCursor<'_>) -> Result<()> {}
    fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> Result<usize> {}
    fn is_read_vectored(&self) -> bool {} // considered with `read_vectored`
    fn read_exact(&mut self, buf: &mut [u8]) -> Result<()> {}
    fn read_to_end(&mut self, buf: &mut Vec<u8>) -> Result<usize> {}
    fn read_to_string(&mut self, buf: &mut String) -> Result<usize> {}
}
impl Read for T buf buf_exact vectored exact to_end to_string
&mut Read 1 2 3 4 5 5
Box<Read> 1 2 3 4 6 6
&[u8] 1 2 3 4 7
VecDeque<u8> 8 8 7 7
std::io::Chain<Read, Read> 9 3 9 9
std::io::Take<Read> 1
std::io::Empty 10 10 10 10 10
std::io::Repeat 1 11 3 4 11
std::io::Cursor<AsRef<[u8]>> 1 2 3 4 12 12
std::io::BufReader<Read> 1 2 3 4
std::net::TcpStream 13 3 4
&std::net::TcpStream 13 3 4
std::os::unix::net::UnixStream 14 3 4
&std::os::unix::net::UnixStream 14 3 4
&std::sys::net::windows::Socket15
std::io::PipeReader
&std::io::PipeReader
std::fs::File 1 ✅/✅4
&std::fs::File 1 ✅/✅4
Arc<std::fs::File>
std::sys::fs::hermit::File 16 N/A N/A N/A N/A
std::sys::fs::solid::File N/A N/A N/A N/A
std::sys::fs::unix::File 1 N/A ✅/✅4 N/A N/A N/A
std::sys::fs::unsupported::File 1 N/A N/A N/A N/A
std::sys::fs::wasi::File 13 N/A ✅/✅4 N/A N/A N/A
std::sys::fs::windows::File 1 N/A ✅/✅4 N/A N/A N/A
&std::sys::unix::fd::FileDesc 1 ✅/✅4
std::sys::fs::unix::CachedFileMetadata
std::sys::windows::handle::Handle 1
&std::sys::hermit::fd::FileDesc17
std::io::Stdin 13 2 ✅/✅4
&std::io::Stdin 18 2
std::io::StdinLock<'_> 13 2 ✅/✅4
std::io::stdio::StdinRaw 13 19 ✅/✅4 19
std::process::ChildStdout 13 ✅/✅4
std::process::ChildStderr 13 ✅/✅4 12
std::sys::stdio::sgx::Stdin 20 20
std::sys::stdio::trusty::Stdin
std::sys::stdio::uefi::Stdin
std::sys::stdio::unix::Stdin 13 ✅/✅4
std::sys::stdio::unsupported::Stdin 19 19 19 19 19 19
std::sys::stdio::wasi::Stdin 21 ✅/✅4
std::sys::stdio::windows::Stdin
std::sys::stdio::zkvm::Stdin 22 23
cargo::util::FileLock
cargo::util::LimitErrorReader<Read>

Write

pub trait Write {
    fn write(&mut self, buf: &[u8]) -> Result<usize>;
    fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> Result<usize> {}
    fn is_write_vectored(&self) -> bool {} // considered with `write_vectored`
    fn write_all(&mut self, buf: &[u8]) -> Result<()> {}
    fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> Result<()> {}
    fn write_fmt(&mut self, fmt: fmt::Arguments<'_>) -> Result<()> {}
    fn flush(&mut self) -> Result<()>;
}
impl Write for T vectored all all_vectored fmt
&mut Write 3 4 5 24 5
Box<Write> 3 4 6 24 6
&mut [u8] 3 4 5 25
Vec<u8> 3 4 5 25 #137762
VecDeque<u8> 7 25 #137762
std::io::Cursor<&mut [u8]> 3 4 25 25
std::io::Cursor<&mut Vec<u8>> 3 4 25 25 #137762
std::io::Cursor<Vec<u8>> 3 4 25 25 #137762
std::io::Cursor<Box<[u8]>> 3 4 25 25
std::io::Cursor<[u8; N]> 25 25
core::io::BorrowedCursor<'_> 25 25 25
std::io::BufWriter<Write> 3 4
std::io::LineWriter<Write>
std::io::…::LineWriterShim<'_, Write>
std::io::Empty 10 10 10
&std::io::Empty 10 10 10
std::io::Sink 3 4 10 10 10
&std::io::Sink 10 10 10
std::net::TcpStream 3 4
&std::net::TcpStream 3 4
std::os::unix::net::UnixStream 3 4
&std::os::unix::net::UnixStream 3 4
std::io::PipeWriter
&std::io::PipeWriter
std::fs::File ✅/✅4
&std::fs::File ✅/✅4
Arc<std::fs::File>
std::sys::fs::hermit::File N/A N/A N/A
std::sys::fs::solid::File N/A N/A N/A
std::sys::fs::unix::File N/A N/A N/A
std::sys::fs::unsupported::File N/A N/A N/A
std::sys::fs::wasi::File ✅/✅4 N/A N/A N/A
std::sys::fs::windows::File ✅/✅4 N/A N/A N/A
std::sys::fs::unix::CachedFileMetadata
std::io::Stdout ✅/✅4
&std::io::Stdout
std::io::StdoutLock<'_> ✅/✅4 26
std::io::stdio::StdoutRaw ✅/✅4
std::io::Stderr ✅/✅4
&std::io::Stderr
std::io::StderrLock<'_> ✅/✅4 26
std::io::stdio::StderrRaw ✅/✅4
std::process::ChildStdin ✅/✅4
&std::process::ChildStdin
std::sys::stdio::sgx::Stdout 20
std::sys::stdio::sgx::Stderr 20
std::sys::abi::sgx::panic::SgxPanicOutput TODO
std::sys::stdio::solid::{Stdout, Stderr} 27
std::sys::stdio::teeos::{Stdout, Stderr} 28
std::sys::stdio::trusty::Stdout #138876 #138876
std::sys::stdio::trusty::Stderr #138876 #138876
std::sys::stdio::uefi::Stdout
std::sys::stdio::uefi::Stderr
std::sys::stdio::unix::Stdout ✅/✅4
std::sys::stdio::unix::Stderr ✅/✅4
std::sys::stdio::unsupported::{Stdout, Stderr} 19 19 19
std::sys::stdio::wasi::Stdout ✅/✅4
std::sys::stdio::wasi::Stderr ✅/✅4
std::sys::stdio::windows::Stdout
std::sys::stdio::windows::Stderr
std::sys::stdio::xous::Stdout upcoming
std::sys::stdio::xous::Stderr upcoming
std::sys::stdio::xous::PanicWriter
std::sys::stdio::zkvm::Stdout 23
std::sys::stdio::zkvm::Stderr 23
test::console::OutputLocation<Write> WIP
test::term::WinConsole<Write> WIP
test::term::TerminfoTerminal<Write> WIP
proc_macro::bridge::buffer::Buffer
rust-installer::compression::CombinedEncoder
rustc_errors::emitter::Buffy
rustc_errors::json::…::BufWriter WIP
cargo::util::FileLock

FileExt

Type read_at seek_read read_vectored_at read_exact_at write_at seek_write write_vectored_at write_all_at
std::fs::unix::fs::File N/A 29 default N/A 29 default
std::sys::wasi::fs::File default N/A default default N/A default
std::sys::windows::fs::File N/A N/A N/A N/A N/A N/A

Socket

Type read read_buf read_vectored recv_from peek peek_from write write_vectored
std::sys::net::hermit::Socket 30 ✅/✅4 ✅/✅4
std::sys::net::solid::Socket
std::sys::net::unix::Socket 13 3 4 3 4
std::sys::net::wasip2::Socket default private default
std::sys::net::windows::Socket 13 3 4 3 4
std::sys::net::sgx::{TcpStream, UdpSocket} 20 3 4 unsupported unsupported (ok) unsupported 3 4
std::sys::net::wasip1::{TcpStream, UdpSocket} 13 3 4 unsupported unsupported unsupported 3 4

Footnotes

  1. Added in Implement most of RFC 2930, providing the ReadBuf abstraction #81156. 2 3 4 5 6 7 8 9 10 11 12 13 14

  2. Added in Specialize many implementations of Read::read_buf_exact #122393. 2 3 4 5 6 7 8

  3. Added in Add vectored read and write support #58357. 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33

  4. Added in Add Read/Write::can_read/write_vectored #67841. 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62

  5. Added in std: Update the std::io adaptors to proxy all methods #22428. 2 3 4 5 6

  6. Added in std: Stabilize portions of the io module #23010. 2 3 4

  7. Added in Specialize some io::Read and io::Write methods for VecDeque<u8> and &[u8] #110608. 2 3 4

  8. Added in Specialize read_exact and read_buf_exact for VecDeque #132039. 2

  9. Added in Specialize some methods of io::Chain #105917. 2 3

  10. Added in Implement default methods for io::Empty and io::Sink #137051. 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17

  11. Added in Implement read*_exact for std:io::repeat #136818. 2

  12. Added in Improve several Read implementations #122441. 2 3

  13. Added in Implement read_buf for a few more types #108326. 2 3 4 5 6 7 8 9 10 11 12

  14. Added in UnixStream: override read_buf #123084. 2

  15. This Read implementation is unused. I plan to remove it.

  16. Added in Implement read_buf for Hermit #138301.

  17. This Read implementation is unused. I plan to remove it.

  18. Added in Add Read Impl for &Stdin #99153.

  19. Added in Provide optional Read/Write methods for stdio #136769. 2 3 4 5 6 7 8 9 10 11

  20. Added in Implement read_buf and vectored read/write for SGX stdio #137355. 2 3 4 5

  21. Added in Implement read_buf for WASI stdin #137353.

  22. Added in Implement read_buf for zkVM stdin #137349.

  23. zkVM has no vectored read/write syscalls. 2 3

  24. Added in Forward all default methods for I/O impls #137062. 2

  25. Added in Override default Write methods for cursor-like types #137107. 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16

  26. StdoutLock<'_> and StderrLock<'_> cannot provide write_fmt, because the user could supply a formatting implementation which uses Stdout or Stderr, leading to panicking. (See joboet's comment) 2

  27. SOLID has no vectored version of SOLID_LOG_write.

  28. TEEOS has no vectored version of KCALL_DEBUG_CMD_PUT_BYTES.

  29. Added in Add vectored positioned I/O on Unix #89518. 2

  30. Added in Implement read_buf for RustHermit #109722.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-ioArea: `std::io`, `std::fs`, `std::net` and `std::path`C-tracking-issueCategory: An issue tracking the progress of sth. like the implementation of an RFCT-libsRelevant to the library team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions