Pre-RFC: allow retreiving foreign items from proc macros


#1

Summary

Allow to define a proc macro as fn(TokenStream, TokenStream, &Source) -> TokenStream where Source provides fn get_item(item: &[String]) -> Option<TokenStream>, which returns the definition of item.

For example source.get_item(&["std", "option", "Option"]) would return the definition of Option type. It’d work with any type or trait in any crate.

Proc macro is invoked as function-like macro: example!(MyType).

Motivation

There is delegation RFC, Inherent trait implementation RFC. Both request to add new syntax to the language which could be implemented as a proc macro, if this feature was available today. One could e.g. write delegate!(MyTrait to MyType::inner) to delegate the MyTrait to inner field of MyType. Similarly, one could write inherent!(MyType, MyTrait) to make trait methods of MyTriat inherent to MyType.

Further, it’d help when writing (de)serializers. Let’s say I have my own MySerialize trait and associated derive macro. The crate implementing derive macro could also provide foreign_derive!() one, and reuse the code of classic derive macro. Then the crate defining MySerialize could easily implement it for types from other crates.

Similarly, a macro using newtype pattern could implement foreign traits for “foreign” types.

This would allow us experiment with delegation, inherent impls and possibly other ideas the same way we could experiment with try!() macro before implementing ? operator.

What do you think? Is this approach feasible? Do you see some problems? Anyone willing to help me with writing proper RFC?


#2

This works for derive macros, as those don’t touch the inners of an item definition.

But otherwise, you start running into ordering issues.

If you have a proc macro that emits an item definition, you’d probably expect to be able to access its definition via this API. That means that the macro emitting an item definition has to run before yours.

This isn’t an unsolvable problem (probably). But the question does need to be answered; relying on macro expansion order for correctness is scary.