Part 1: Trait Aliases
The trait_alias unstable feature enables syntax like this:
#![feature(trait_alias)]
trait Foo = std::fmt::Debug + Send;
trait Bar = Foo + Sync;
// Use trait alias as bound on type parameter.
fn foo<T: Foo>(v: &T) {
println!("{:?}", v);
}
However, the resulting traits (Foo and Bar) in the above example cannot be implemented on types.
error[E0404]: expected trait, found trait alias `Foo`
--> src/main.rs:8:6
|
8 | impl Foo for A {
| ^^^ not a trait
My suggestion comes in two parts:
- Enable trait aliases to contain multiple regular traits, not just a single regular trait and multiple auto traits.
- Implementing a trait alias for a type would be the same as if that trait alias were a regular trait with all of the member functions, types, and constants of the constituent traits combined (name conflicts would be a compile error), except that implementing the trait alias implements the constituent traits instead.
Part 2: Adding io::Read and io::Write to core
If the above suggestion was implemented, Read and Write traits could be added to core as subsets of the full trait in std. For example (using the full paths, even though it's invalid syntax):
trait core::io::Read {
type Error;
fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error>;
// ... the other methods that don't require allocation
}
And then, std::io::Read would be reimplemented as a trait alias:
trait std::io::Read = core::io::Read<Error = std::io::Error> + alloc::io::ReadExt;
where
trait alloc::io::ReadExt: core::io::Read {
// ... all the read methods that require allocation
}
The same applies to the std::io::Write trait. It would require careful planning to make sure there was no breakage, but I think this would be possible.
I'm very curious what people think of this proposal—whether it's desirable to even add io traits to core, whether this proposal would actually work, and any comments or criticism.