[Idea] Lowering `std::io` to core


Hey all.

I’m not sure of this suggestion is a breaking change, but if it is, it’s pretty minor and can be bundled in the 2018 Edition.

I think it is a good idea to lower the Read/Write traits into libcore.

Embedded applications still perform IO (as any application does, I guess), and having the traits to support it can help standardize the interface.

If I want to write a library that abstracts over Read, it is now automatically requires stdlib, even though all I use is a couple of traits. This requires me to write an identical trait in my crate, but it will never compose ergonomically with the ones defined in stdlib or with libraries using it.

Having the traits in std also prevents nostd applications from using a simple functionality of &[u8]; read() & write().

This concern has spawned https://github.com/QuiltOS/core-io (which is unmaintained AFAIK).

Lowering the traits into libcore might absolutely causes breakage though, as even the most basic traits in std::io depend on liballoc:

  • std::io::error::Repr has a variant Custom which contains a Box<Error>
  • std::io::Read has read_to_end and read_to_string, which depend on Vec<u8> and String, respectively.

I don’t think Rust currently has the mechanisms needed in order to support this change without breaking compatibility, but I would love to hear if anyone has any idea if it’s achievable.


Editions can’t change the standard libraries like this.

There’s lots of historical discussion on this, you should check it out. Allocation is the big issue here, as you mention.


Oh well. This seems like a lost cause, isn’t it? A shame, since the core definitions doesn’t even allocate anything interesting.


The portability lint should eventually allow #![no_std]-like applications that depend on a more granularly-defined subset of std than just "core vs std." This would let you do what you want, even to the point of omitting read_to_end/read_to_string in applications with no global allocator.

I imagine at that point we could move everything into std and reduce core to a compatibility crate that re-exports the things it used to define.