Search code examples
rustenumsdispatchenum-dispatch

How to use two traits with enum_dispatch?


I've tried:

#[enum_dispatch(BarTrait, BazTrait)]
pub enum Foo {
    VariantZero,
    ...
}

It seems to ignore any traits after the first, silently.

This causes errors, as in this case the compiler doesn't seem to believe that Foo implements BazTrait.


Update: @kmdreko's code works properly so long as BazTrait is in the same crate as Foo.

When BazTrait is in a different crate, which also uses enum_dispatch, BazTrait is ignored and causes two errors of the form:

error[E0599]: no method named `baz` found for enum `Foo` in the current scope
  --> src/main.rs:53:9
   |
45 | enum Foo {
   | -------- method `baz` not found for this
...
53 |     foo.baz();
   |         ^^^ method not found in `Foo`
   |
   = help: items from traits can only be used if the trait is implemented and in scope
   = note: the following trait defines an item `baz`, perhaps you need to implement it:
           candidate #1: `mylib::BazTrait`

It is important to note that there is no error at either #[enum_dispatch(BarTrait, BazTrait)] or pub enum Foo {.


Solution

  • The #[enum_dispatch] attribute does not work across crates:

    Unfortunately, procedural macros in Rust are limited in a few ways that will make what you're trying to achieve impossible - notably, they are run independently per-crate, so there's no way for information from one crate to affect an implementation in another.

    From the author of enum_dispatch in an unrelated issue.