Visualizing Rust's Vtables: How dyn Trait Works In Memory

169 points - yesterday at 1:31 PM

Source

Comments

tialaramex yesterday at 9:55 PM
This has a section on Object Safety, I checked and the article was written this week, but "Object Safety" is a confusing name for this idea, and so for a little while now Rust calls this idea "dyn compatibility" because the most important thing you're getting if a trait is "dyn compatible" is that you can use "dyn Trait" - https://doc.rust-lang.org/1.98.1/reference/items/traits.html...

That link more comprehensively explains the rules too.

[Edit: Realized the end of the article explains this, the author began writing it months ago, likely before they read about the improved "dyn compatibility" naming]

evmar today at 1:36 AM
In my own journey of discovery I found https://cheats.rs/ very helpful, and in particular its "memory layout" section has visualizations. (No affiliation with the site, just a happy reader!)
Panzerschrek today at 5:46 AM
> A trait must follow so-called object safety rules to be used as a trait object

This seems for me to be a major design flaw of Rust. It tries to repurpose traits for dynamic polymorphism, even if this doesn't fit perfectly. C++ is more honest, it has two separate mechanisms for static polymorphism (templates) and dynamic polymorphism (inheritance).

Panzerschrek today at 5:44 AM
I once faced a tricky bug involving fat pointers (containing virtual tables) in Rust. Two such pointers may be distinct, even if they reference to the same object, because (for some reason) the compiler may create two (or even more) copies of the virtual functions table and use them in different places.
returningfory2 yesterday at 9:46 PM
Very nice. As a follow up would be interesting to also reverse engineer the structure of the vtable itself. I guess it’s a list of pointers to the method implementations?
ketzu yesterday at 8:20 PM
> In Rust, that question is answered by the borrow-checker at compile time:

(About zero sized objects being the same)

But why does that mean the programmer never has to check? (or if they want that information from the borrow checker how would they get it?) It's not motivated as the intro above for c++ was just "In C++, we might do this to check if two pointers refer to the same object".

So the borrow checker knows already, why does that stop the programmer from wanting to know or separate these cases?

Waterluvian today at 12:48 AM
I never did well in English and I usually don’t know it when I see it. But it was immediately evident that the writing style of this blog was sparking joy. Even the intro section was just so well structured that I had to read it again.
7e today at 1:09 AM
The title includes the word “visualizing” but there is not a single diagram in this article. Is English not the first language of the author?