Dyn multiple traits in a type alias

I have 2 generic traits: A & B and i want to create a type alias to something like:

Arc<Mutex<dyn A<T> + B<T>>>

here is a playground:

this doesn't compile.

i ended up creating a 3rd trait C which just combines A and B.. though maybe that isn't the right approach?

If i remove the type annotation for the let x statement then it will compile and run just fine, but i want to be able to store a shared pointer to an object that impl both A and B and pass that to methods with just require one of those.

Ideas?

i've looked into this as well, and doesn't seem to be possible at the moment—apart from the work-around of manually creating a combined trait, as you say—due to some unresolved issues around the combinatorial blowup that would otherwise arise with vtables

there is related discussion here:
https://github.com/rust-lang/rfcs/issues/2035

2 Likes

apart from the work-around of manually creating a combined trait

but even the combined trait isn't working for me.

is there a way to call a function that takes an
Arc<Mutex<dyn B<T>>> with an Arc<Mutex<dyn C<T>>> where C includes B ?

I'm fine to have the combined trait as i should be able to automatically implement it.. though it would be nice to not even require that.

There are a couple of approaches to consider.

First, define a trampoline API in the traits to “convert” from one type to another. For example:

trait B {
   fn as_A(&self) -> &A;
}

trait A {
   fn as_B(&self) -> &B
}

The impls just return self since they implement both traits.

You lose the Arc aspect - don’t know if that’s pertinent. Arbitrary self types may make this better in the future.

Second option is to abstract the functionality you want into another trait, which your functions want, and impl that trait for Arc<Mutex<dyn C>> (or whichever trait objects). So then you wouldn’t need to get a Arc<Mutex<dyn B>> from a Arc<Mutex<dyn C>> - you’d just pass the latter directly.

Don’t know if any of these help but worth considering.

1 Like

The Arc is pretty important in this but for now I can actually just use a concrete type instead of my Arc<Mutex<dyn C>> and this type impl's both A and B so I'm all set. It just seemed like it would be nice to be able to define an alias that indicates that the contained object implements both A and B and be able to use that in place of either Arc<Mutex<dyn A>> or Arc<Mutex<dyn B>> but I think I'll be okay without that.

Thanks!