Reflection MVP by oli-obk · Pull Request #146923 · rust-lang/rust (original) (raw)
I am opening this PR for discussion about the general design we should start out with, as there are various options (that are not too hard to transition between each other, so we should totally just pick one and go with it and reiterate later)
r? @scottmcm and @joshtriplett
project goal issue: rust-lang/rust-project-goals#406
tracking issue: #146922
The design currently implemented by this PR is
TypeId::info(method, usually used asid.info()returns aTypestruct- the
Typestruct has fields that contain information about the type - the most notable field is
kind, which is a non-exhaustive enum over all possible type kinds and their specific information. So it has aTuple(Tuple)variant, where the only field is aTuplestruct type that contains more information (The list of type ids that make up the tuple). - To get nested type information (like the type of fields) you need to call
TypeId::infoagain. - There is only one language intrinsic to go from
TypeIdtoType, and it does all the work
An alternative design could be
- Lots of small methods (each backed by an intrinsic) on
TypeIdthat return all the individual information pieces (size, align, number of fields, number of variants, ...) - This is how C++ does it (see https://lemire.me/blog/2025/06/22/c26-will-include-compile-time-reflection-why-should-you-care/ and https://isocpp.org/files/papers/P2996R13.html#member-queries)
- Advantage: you only get the information you ask for, so it's probably cheaper if you get just one piece of information for lots of types (e.g. reimplementing size_of in terms of
TypeId::infois likely expensive and wasteful) - Disadvantage: lots of method calling (and
Optionreturn types, or "general" methods likenum_fieldsreturning 0 for primitives) instead of matching and field accesses - a crates.io crate could implement
TypeId::infoin terms of this design
The backing implementation is modular enough that switching from one to the other is probably not an issue, and the alternative design could be easier for the CTFE engine's implementation, just not as nice to use for end users (without crates wrapping the logic)
One wart of this design that I'm fixing in separate branches is that TypeId::info will panic if used at runtime, while it should be uncallable