How to disassemble a trait object pointer?

Having *mut dyn Trait, how do I retrieve the vtable pointer and the data pointer as separate values?

I mean it is just two pointers next to each other, so you can split them up. You should however be aware that doing this is undefined behaviour, even if it works, because the layout of trait object pointers is undefined.

Undefined or unspecified? I mean, is it guaranteed that with given version of the toolchain the result will be consistent?

I don't think Rust makes any explicit guarantees about the layout of trait object pointers at all.

In nightly you can use https://doc.rust-lang.org/std/raw/struct.TraitObject.html, but as @alice said, this is an unstable feature, the layout ins't guaranteed yet.

3 Likes

What are you trying to do with the split ptr & vtable tuple?

1 Like

I'm trying to store a contiguous array where trait objects are not located behind a pointer, as long as all elements have the same size. This would mean that I'd need to store the vtable pointer and the object itself rather than a pointer to the object.

That's interesting, does the (possibly heterogeneous) array a compiletime fixed size? If so, you can use another (more involved) way to get a similar construct on stable with only safe code.

This is something incredibly tricky to do right, but it can indeed be done. You will not be able to have [idx] sugared indexing on stable rust, as that would require being able to yield a &'_ [mut] dyn Trait when indexed, which you will not be able to do without feature(raw) (some very ugly type-level-wise abuses, which I advise against).

  • Without the feature and the sugared indexing, by using manually laid out vtables and custom wrapper types representing &'_ [mut] (dyn Trait + 'static), you could have it working on stable Rust, but that would also require perfect knowledge of the trait you'd be working on, so if you want to support multiple traits then, you'd need some macro (e.g., a procedural one) to ease the job / avoid code duplication.

  • Playground 1 (targeting one specific trait)

  • Playground 2 (targeting any trait thanks to Unsize)

3 Likes

Wow! I reviewed Playground 2 above. What a fantastic, complex, complete solution! You post these so frequently that you should have a Patreon account to which people whose problems you solve should contribute in gratitude.

1 Like