Just allowing dyn Trait1 + Trait2
has its own implementation problems (see for example Where's the catch with Box<Read + Write>? and Sieve-tables for multiple traits objects (Box<A+B+C> to Box<A+C>, #2035)) except when the additional traits are autotraits, e.g. Send
or Sync
, for which this is already possible.
The alternative for now is to create a new trait with all the bounds with a blanked implementation. So instead of Box<dyn Trait1 + Trait2>
you would have Box<dyn CombinedTrait>
where CombinedTrait
is defined as follows:
trait CombinedTrait : Trait1 + Trait2 {}
impl<T: Trait1 + Trait2 + ?Sized> CombinedTrait for T {}
Even then though it wouldn't work for your particular case because neither Hash
nor Eq
are object safe traits. For Hash
this is because it contains generic functions, which correspond to infinite concrete functions, so they cannot be included in the trait object vtable. For Eq
this is because types implementing it expect to only ever be compared with other instances of the same type, but with dyn Eq
you could compare a type with a completly different one.
I don't think they will ever become object safe (maybe Hash
, but definitely not Eq
), so you have to solve this manually. @quinedot already showed how make object-safe variants of them so that you can implement Hash
and Eq
for dyn YourTrait
, and that's the correct solution:
You should implement them for dyn YourTrait
because it's a local type in your crate, then Box
will automatically implement them whent he inner type implements them.