Follow this model, cited from here.
// for example, the vtables for i32 and Vec<i32>
static VTABLE_FOO_FOR_I32: VTableFoo = VTableFoo { ... };
pub struct TraitObjectFoo {
data: *mut (),
vtable_ptr: &VTableFoo,
}
// let x: &dyn Foo = &10;
let x = TraitObjectFoo{ &10, &Vtable..};
- if I understand correctly
&dyn Foo
is the real fat pointer, then what aboutdyn Foo
?
Back to our example:
fn main() {
// let x: &dyn A = &10;
let x = TraitObjectA{ &10, &VTableAForI32 };
// have a B trait object over dyn A since
// dyn A implements B
let y: &dyn B = x;
}
- what happens to
let y: &dyn B = x;
? Does it first do pattern match?&dynB
match with type&dyn A
, and then the compiler checks whetherdyn B
is implemented fordyn A
(find whether the vtable is existent)?
if so, I think you are right!! Follow the above model, it should be
// let y: &dyn B = x;
// pattern match: remove the &dyn: B matches with A
// assigning a pointer to a fat pointer which is not allowed.
y.data = x; // &dyn A
y.vtable = &VTableBForDynA;
In this way, &dyn B
must construct from sized data. Not sure if my understanding is correct.