[Pre-RFC] Add a new offset_of macro to core::mem


You’re right, there isn’t anything special about them. I just don’t like to have both magic words and magic macros (and magic functions, come to think of it). It makes it easier for me to think about things if all the magic is in the keywords.


I already said in no uncertain terms that I’m not making claims that it will matter in the end. I do however want to make sure we’re all on the same page about what exactly this implementation strategy entails.

Users can and do sometimes look at what macros expand to, using tools such as the third party command cargo expand. If they do that with code involving offset_of! implemented in the way you propose, they will see a peculiarity that other macros won’t show (except asm! and global_asm!): the macro will appear to not be expanded at all. Other built-in macros such as include! or println! will reveal their secrets, but this one won’t and can’t.

I want to stress once again that if you want to argue this difference doesn’t matter, I won’t object. But please be aware that it exists and take it into account.


I wish rust started moving towards metaprogramming and offsetof could be a first step. I. e. offsetof could be a const fn like:

const fn offset_of<T>(field: &str) -> Option<usize>;

It would be a compiler intrinsic.


Monomorphization, and thus full determination of types, is not complete until the end of MIR, just before code generation by LLVM or some other back end. Would you implement the metaprogramming as a multi-pass process, with the compiler executing its phases through MIR before recurring to the much earlier point where macros can modify the AST? What criteria would assure eventual convergence?


Metaprogramming is a broad term. Generating new types on the fly would require multi-pass compiler, but for example implementing a function which serializes object to json (which is currently can only be done with proc macros) would not. The latter is also metaprogramming.


I’d love to see a full-featured compile-time reflection API based on const fn. As a one-off, though, it’s probably not worth it…