I'm playing around the nightly rust and I run into a problem of providing default implementation for traits:
trait Trait {
type Foo<'a>: Future<Output = u32>;
fn foo<'a>(&'a self) -> Self::Foo<'a>;
type FooMany<'a>: Future<Output = ()>;
fn foo_many<'a>(&'a self, out: &mut [u32]) -> FooMany<'a>;
type Bar;
fn bar(&self, bar: Self::Bar);
}
It would be nice if foo_many
could be provided with default implementation:
default trait Tait {
type FooMany<'a> = impl Future<Output = ()>;
fn foo_many<'a>(&'a self, out: &mut [u32]) -> FooMany<'a> {
for elem in out.iter_mut() {
*elem = self.foo().await;
}
}
type Bar = Void;
fn bar(&self, bar: Self::Bar) {
unreachable(bar);
}
}
This won't work as Self::FooMany
is still considered unknown by compiler. Are there any plans to lift the restriction so that such code is allowed?
I would assume that if the restriction is lifted the code:
impl Trait for u32 {
type Foo<'a> = impl Future<Output = u32>;
fn foo<'a>(&'a self) -> Self::Foo<'a> {
async move {
*self
}
}
type FooMany<'a> = ...;
type Bar = something other than void;
}
Would fail with appropiate error.
I will also note that Bar can be workaround by:
trait TraitAux {
type Bar;
}
trait Trait {
type Foo<'a>: Future<Output = u32>;
fn foo<'a>(&'a self) -> Self::Foo<'a>;
type FooMany<'a>: Future<Output = ()>;
fn foo_many<'a>(&'a self, out: &mut [u32]) -> FooMany<'a>;
type Bar;
fn bar(&self, bar: Self::Bar);
}
default impl<T> TraitAux for T {
type Bar = Void;
}
default impl<T: Trait<Bar = Void>> Trait for T {
fn bar(&self, bar: Self::Bar) {
unreachable(bar);
}
}
But it doesn't work for impl Trait
.