I’ve been reading this whole thread of conversation, starting from the tracking issue for std::raw, then moving to the RFC on custom DSTs, and finally to here, because I had an idea about how std::raw::TraitObject could be replaced with something better. Something that lets you do everything you needed TraitObject for, that abstracts away the details of the underlying structure, and is a more general API that can be used on all types. Then I read @nikomatsakis’ comment on the RFC, which he linked to above, and realized he had the same idea.
Specifically I’m referring to the assemble and disassemble functions, that let you split a pointer into its (data_pointer, meta) parts, and put them back together again.
Here is an example of a problem whose solution could be much improved using assemble and disassemble. Yesterday I was creating struct DSTVec<T: ?Sized>, which is a generalization of Vec in that it allows types that are ?Sized. DSTVec would store a value’s data in a RawVec, and have a separate Vec of pointers into that RawVec.
Unfortunately, there was no way to take a *mut T and change where it points to. So I had to change tactics, and define a macro declare_dstvec! that takes the name of a trait and defines the macro for that trait. Here is a Gist.
Using assemble and disassemble, the implementation could be much improved. Here is a revision showing how it would work using the Referent trait. In fact, now that I think of it, I could probably create the Referent trait myself and use it to get rid of the macro!