What are the benefits of using raw vtable? And when this pattern should be used?

I'm reading the code of anyhow::Error and I liked that is using a raw vtable. However I'm trying to understand the reason. Couldn't this be implemented with just traits? What are the technical benefits of using a raw vtable instead of traits?

In general I noticed this pattern in other crates too, for example bytes::Bytes are using raw vtable. Or even std::task::Waker is using raw vtable.

When this pattern should be used?

For anyhow, the reason is so the error type can be eight bytes in size without making two allocations.

4 Likes

I might be wrong but the two reasons I can think of for manual vtables are:

  • A dyn trait is a pointer to the vtable plus a pointer to the instance. If all you need is a pointer to the vtable there's no reason to carry two pointers around. Ditto if the instance pointer itself contains a pointer to the vtable (e.g. as the first member).
  • I believe the implementation of Rust's dyn trait is not guaranteed? A guaranteed layout is important for FFI, etc.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.