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.