Portable (portal?) macros

Just throwing ideas here.

Macros has to be invoked at declaration. What I mean by this is the following:

#[Derive(PrintSignature)]
struct Whatever;

the PrintSignature macro has to be declared with this struct.

But this is often not the ideal way to do things. For something like printing the signature of a struct we shouldn't have to implement a whole new trait for it. What I'm thinking is that we could do is make the macros callable anywhere. We could "portal" the tokens from its declaration site to the macro. For instance:

struct Whatever;

fn main() {
    Whatever#print_signature!()  // example syntax
}

print_signature! would still receive the tokens struct Whatever, but it just doesn't have to be where the declaration is . There's another advantage which is that this can be applied things of other crates as well, which circumvents the orphan rule because we no longer need to implement traits.

Another example: I have a macro which turns a struct into a struct-of-arrays. Basically it creates a new struct but with each field wrapped in a Vec, and adds some convenience functions. Having tokens "teleported" means that I can use this macro for structs from libraries like a vec3d struct or color.

1 Like

What you are describing is basically just reflection, and there is some pre-RFC work being done on that.

1 Like

This is a massive layering problem, so probably won't work like that. You can only know that it's a struct by doing full name resolution, which macros mostly don't do -- they have some hamstrung partial version for non-global macros, but don't know anything about functions or structs or ...

A reflection API that gets type information? Sure. Getting tokens, though? No, probably not. (Especially since I don't want you getting the tokens from the declaration of my struct -- I intentionally used privacy so you can't see the fields, let alone the full set of tokens.)

5 Likes

This is a chicken-egg problem. Macros are expanded before any types are defined.

Macros can generate things that change types and affect name resolution. Letting macros depend on types would risk creating cyclic dependencies, and that's a problematic thing to have in the language.

2 Likes