Non generic enum implementing Generic trait
enum_dispatch works as expected if the enum and trait both are generic, however my requirement is that I will pass concrete types in the enum instead of making it generic over some types.
use enum_dispatch::enum_dispatch;
pub struct Bar<T>(pub T);
pub struct Baz<T>(pub T);
impl<T> FooTrait<T> for Bar<T> {
fn foo(&self) -> &T {
&self.0
}
}
impl<T> FooTrait<T> for Baz<T> {
fn foo(&self) -> &T {
&self.0
}
}
#[enum_dispatch]
pub trait FooTrait<T> {
fn foo(&self) -> &T;
}
#[enum_dispatch(FooTrait<T>)]
enum Foo { // Foo is not generic
Bar(Bar<i32>), // Concrete type passed to the variant
Baz(Baz<i32>),
}
fn main() {
let bar = Bar(1);
let baz = Baz(3);
let x: Foo = Foo::Baz(baz);
let y: Foo = Foo::Bar(bar);
println!("print 3: {}", x.foo());
println!("print 1: {}", y.foo());
}
Compiling above, I get this error
error[E0412]: cannot find type T in this scope
--> src/main.rs:29:1
|
29 | #[enum_dispatch(FooTrait<T>)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not found in this scope
|
cargo expand reports the following expansion for the above code:
impl FooTrait<T> for Foo {
#[inline]
fn foo(&self) -> &T {
match self {
Foo::Bar(inner) => FooTrait::<T>::foo(inner),
Foo::Baz(inner) => FooTrait::<T>::foo(inner),
}
}
}
Is there some way to fix this? I expected an expansion like this:
impl<T> FooTrait<T> for Foo
where
Bar<i32>: FooTrait<T>,
Baz<i32>: FooTrait<T>,
{
fn foo(&self) -> &T {
match self {
Foo::Bar(e) => FooTrait::<T>::foo(e),
Foo::Baz(e) => FooTrait::<T>::foo(e),
}
}
}