You can have dynamic dispatch through trait objects. Not every trait is object-safe though, and object safety basically captures the necessary properties for this to work, eg. the type in question must be behind a pointer so that the generated machine code can work uniformly with any type, whatever its size and alignment. So this special case makes machine code reuse possible with the usually insignificant cost of indirect calls.Yeah, but that's the point. It means you can directly reuse machine code instead of performing a template operation or writing boilerplate.
Everything goes through the vtables. But whereas C++ puts the vtable pointers inside the objects themselves, and this gets quite complicated with multiple inheritance and virtual inheritance, Rust uses fat pointers, meaning that the pointer to an object is paired up with the pointer to the vtable, so it's outside of the object itself. That's why I said there are no restrictions on the internal layout.