Visualizing Rust's Vtables: How dyn Trait Works In Memory
Points and comments are a snapshot, not live.
Rust's dyn Trait uses wide pointers with external vtables, unlike C++'s per-object vtables.
The author compares Rust polymorphism to C++: static dispatch (monomorphization) mirrors CRTP, while dynamic dispatch (dyn Trait) uses a fat pointer (16 bytes) with separate data and vtable pointers, unlike C++ where the vtable pointer lives in the object. Rust's zero-sized types (ZSTs) occupy 0 bytes because identity is tracked by ownership, not addresses; debug mode assigns dummy stack slots. One vtable exists per (type, trait) pair. Object safety rules: methods cannot return Self or have generic parameters. Dynamic dispatch is chosen at the call site, not the type level.
What commenters are saying
Commenters debated whether the borrow checker truly 'knows' identity for ZSTs; several noted ZSTs lack identity by design, and identity checking is possible via pointer equality but yields no useful info. A comment clarified the term 'object safety' has been renamed 'dyn compatibility' in recent Rust. Another pointed out C++ can return objects by value, hitting the same size-knowledge problem Rust avoids. One commenter lamented the article's lack of actual diagrams despite the title.