Building a runtime reflection system for Rust 🦀️ (Part 2)

Nice read!! A few comments:

The entire instance is pinned: this method takes Pin<&mut Self> .

Careful with Pin, and careful with making too much publicity for it: it is a subtle wrapper. For instance, the statement alone "it is pinned because Pin<&mut Self>" is wrong: something is pinned if behind a Pin-wrapped pointer, such as Pin<&mut Self>, and is Pin-aware / is unable to unpin itself / is !Unpin.

  • And then once you get something correctly pinned, the whole thing becomes less ergonomic to work with. So I'd definitely favor the getter approach (which gets to be shared for all Instances of a same Class, where the self-referential pointer required that all pinned Instances carried them with them.

An alternative to self-referential pointers are offset-based pointers, which in this case, now that I think of it, could make a lot of sense:

  • the offsets are type-based, so they can be stored within the class,

  • the offsets can be computed by a (proc-) macro,

  • they single1-handedly solve the issues pointed out by:

1 At the meager cost of a #[repr(C)] attribute

Obviously, all this would be a micro-optimization more than anything else, but maybe one worth keeping in the back of the one's head :slightly_smiling_face:


Another micro-optimization (super tiny, to be fair): I feel like this could be using fn(&Instance) -> PolarValue pointer-types rather than Arc<dyn Fn...>. It will save a few atomic {in,de}crements and one level of pointer indirection, and reduce the size of its containing struct by one usize :slightly_smiling_face:

1 Like