// traits describing aspects of functionality needed elsewhere
trait A {}
trait B {}
// provider of functionality is always expected to support both
trait AB {}
impl<T: A + B> AB for T {}
struct Provider0 {}
impl A for Provider0 {}
impl B for Provider0 {}
// provider is picked dynamically at runtime
fn new_ab(i: u8) -> Box<dyn AB> {
match i {
0 => Box::new(Provider0 {}),
_ => unimplemented!(),
}
}
use std::sync::Arc;
fn use_a(a: Arc<dyn A>) {}
fn use_b(b: Arc<dyn B>) {}
fn run() {
let x = new_ab(0);
let x: Arc<dyn AB> = Arc::from(x);
use_a(x.clone());
use_b(x);
}
error[E0308]: mismatched types
--> src/lib.rs:28:11
|
28 | use_a(x.clone());
| ^^^^^^^^^ expected trait `A`, found trait `AB`
|
= note: expected struct `std::sync::Arc<(dyn A + 'static)>`
found struct `std::sync::Arc<dyn AB>`
error[E0308]: mismatched types
--> src/lib.rs:29:11
|
29 | use_b(x);
| ^ expected trait `B`, found trait `AB`
|
= note: expected struct `std::sync::Arc<(dyn B + 'static)>`
found struct `std::sync::Arc<dyn AB>`
The functionality provided by the traits is identical in behavior, however the context is completely disjoint so making consumers accept Arc<dyn AB>
would be wrong and adding a dependency that doesn't really exist (and having to resolve naming conflicts as the names of the methods are the same in both traits.)
Is there a way to return a trait object implementing multiple traits and pass that object as parameter to function expecting the individual trait objects wrapped in Arc
?