Implement default methods for io::Empty and io::Sink by thaliaarchi · Pull Request #137051 · rust-lang/rust (original) (raw)

I've added tests for the new impls.

I also decided to keep Empty::is_read_vectored as the default false. I see it this way: Empty has nothing to read, so we don't need to read that nothing in larger batches; Sink can write large amounts cheaply, so we should batch those writes as large as possible.

In the standard library, only Chain<T, U> non-trivially uses is_read_vectored. It returns true when either of its inner Readers returns true. With Empty in a chain, if Empty::is_read_vectored() == true, it would force the other to use vectored reads:

fn is_read_vectored(&self) -> bool {
self.first.is_read_vectored() |
}

This could be somewhat improved by making it conditional on whether the first has finished (but then constant propagation is probably worsened):

fn is_read_vectored(&self) -> bool { if !self.done_first { self.first.is_read_vectored() } else { self.second.is_read_vectored() } }

In the standard library, only BufWriter<W> and LineWriterShim<'a, W> non-trivially use is_write_vectored. They select a writing strategy based on the inner writer's is_write_vectored. With Sink::is_write_vectored() == true (as currently), it does less work, because it batches more (nop) writes together. But, vectored or not, a buffered sink is admittedly dumb.