error[E0308]: mismatched types
--> src/main.rs:15:34
|
15 | my_struct.my_struct_func(self);
| ^^^^
| |
| expected struct `Box`, found `&Self`
| help: store this in the heap by calling `Box::new`: `Box::new(self)`
|
= note: expected struct `Box<(dyn MyTrait + 'static)>`
found reference `&Self`
= note: for more on the distinction between the stack and the heap, read https://doc.rust-lang.org/book/ch15-01-box.html, https://doc.rust-lang.org/rust-by-example/std/box.html, and https://doc.rust-lang.org/std/boxed/index.html
I tried some things without success (like my_struct.my_struct_func(&self as Box<dyn MyTrait>); or my_struct.my_struct_func(Box::new(self));).
The basic problem is that MyStruct1::my_struct_func wants a boxed trait object Box<dyn MyTrait>, but MyTrait::my_func takes a shared reference &self. You can fix the mismatch by having MyTrait::my_func take Box<Self> as a receiver, like this:
trait MyTrait {
fn my_func(self: Box<Self>) where Self: 'static + Sized {
let my_struct = MyStruct1 {};
my_struct.my_struct_func(self as Box<dyn MyTrait>);
}
}
(I'm not quite sure why Self: Sized is needed here...)
It's needed to allow a coercion between Box<Self> and Box<dyn MyTrait>, because unsized types can implement MyTrait, but pointers to unsized types can't (in general) be coerced into pointers to MyTrait
Right, once you have a trait object it only has a single vtbl: for the trait it represents. You cannot then “discover” another vtbl for some other trait the underlying value may implement.
That’s not a complete answer, because non-dyn unsized types, like [u32], are also forbidden from being turned into trait objects. You can also impl TraitB for dyn TraitA, but can’t cast dyn TraitA into dyn TraitB.
The information in the second field of the original fat pointer needs to needs to be stored somewhere, and there’s simply no place for it to go. It can’t be stored on the heap without an allocation. If you add it as a third field to the pointer, then that’s no longer the same layout as &dyn Trait; it would have to be a new type.