How would I implement function get_b() that returns parametrised trait with trait? I.e I'd like to have multiple implementations over B parametrised by A that would be dynamically resolved.
trait A {
fn a(&self);
}
trait B<T: A> {
fn b(&self) -> T;
}
struct AA;
impl A for AA {
fn a(&self) {
print!("a for aa");
}
}
struct BB;
impl B<AA> for BB {
fn b(&self) -> AA {
AA{}
}
}
fn get_a() -> Box<dyn A> {
Box::new(AA{})
}
fn get_b() -> Box<dyn B<dyn A>> {
Box::new(BB{})
}
The error I get is:
| ^^^^^^^^^^^^^^ the trait `B<(dyn A + 'static)>` is not implemented for `BB`
Given the signature of B::b (you can't return a dynamically sized type T: A + ?Sized and dyn A is dynamically sized), I think your best bet would be to add another box around the inner dyn A:
trait A {
fn a(&self);
}
trait B<T: A> {
fn b(&self) -> T;
}
struct AA;
impl A for AA {
fn a(&self) {
print!("a for aa");
}
}
impl A for Box<dyn A> {
fn a(&self) {
(**self).a()
}
}
struct BB;
impl B<AA> for BB {
fn b(&self) -> AA {
AA {}
}
}
impl B<Box<dyn A>> for BB {
fn b(&self) -> Box<dyn A> {
Box::new(AA {})
}
}
fn get_a() -> Box<dyn A> {
Box::new(AA {})
}
fn get_b() -> Box<dyn B<Box<dyn A>>> {
Box::new(BB {})
}
fn main() {
let b = get_b();
b.b().a();
}
(This section is basically a repeat of what @jofas said).
In this example, the parameter of B must be Sized (which is a default bound in that position, and also required because you return T by value from B::b). So T can't resolve to dyn A + '_.
Next, the only implementor of B<_> in your OP is B<AA> for BB. If you want a Box<dyn B<Box<dyn A>>>, you have to have an implementation of B<Box<dyn A>> somewhere.
I'm not sure if it actually does what you want it to do or not, though.
You may have some misconceptions around dyn Trait being a subtype of every implementor of Trait or otherwise representing every implementor of Trait automatically. If so, perhaps this overview will help clarify some things.