"impl trait" not supported
Rust 1.75.0 stabilized return position "impl Trait" in Trait methods 1. Structs that implement such traits cannot be made into trait objects. That sounds like a great reason to use enum_dispatch! But it currently doesn't work. For example:
use std::ops::Deref;
use enum_dispatch::enum_dispatch;
#[enum_dispatch]
pub trait Foo {
fn iter(&self) -> impl Deref<Target=[u8]>;
}
pub struct V(Vec<u8>);
impl Foo for V {
fn iter(&self) -> impl Deref<Target=[u8]> {
&self.0[..]
}
}
pub struct A([u8; 4]);
impl Foo for A {
fn iter(&self) -> impl Deref<Target=[u8]> {
&self.0[..]
}
}
#[enum_dispatch(Foo)]
pub enum Bar {
V(V),
A(A)
}
Compiling this will produce the error:
error[E0308]: `match` arms have incompatible types
--> src/lib.rs:26:1
|
13 | fn iter(&self) -> impl Deref<Target=[u8]> {
| ----------------------- the expected opaque type
...
21 | fn iter(&self) -> impl Deref<Target=[u8]> {
| ----------------------- the found opaque type
...
26 | #[enum_dispatch(Foo)]
| ^^^^^^^^^^^^^^^^^^^^^
| |
| expected opaque type, found a different opaque type
| this is found to be of type `impl Deref<Target = [u8]>`
| `match` arms have incompatible types
|
= note: expected opaque type `impl Deref<Target = [u8]>` (opaque type at <src/lib.rs:13:23>)
found opaque type `impl Deref<Target = [u8]>` (opaque type at <src/lib.rs:21:23>)
= note: distinct uses of `impl Trait` result in different opaque types
= note: this error originates in the attribute macro `enum_dispatch` (in Nightly builds, run with -Z macro-backtrace for more info)
help: you could change the return type to be a boxed trait object
|
26 | Box<dynum_dispatch(Foo)]>
| ~~~~~~~ +
help: if you change the return type to expect trait objects, box the returned expressions
|
26 | Box::new(#[enum_dispatch(Foo)])
| +++++++++ +
For more information about this error, try `rustc --explain E0308`.
error: could not compile `enum-dispatch-impl-trait` (lib) due to 1 previous error
warning: build failed, waiting for other jobs to finish...
error: could not compile `enum-dispatch-impl-trait` (lib test) due to 1 previous error
And examining the generated code with cargo expand shows the reason why:
impl Foo for Bar {
#[inline]
fn iter(&self) -> impl Deref<Target = [u8]> {
match self {
Bar::V(inner) => Foo::iter(inner),
Bar::A(inner) => Foo::iter(inner),
}
}
}
enum_dispatch must Box those Foo::iter statements. Would it be possible to make this work?