/rust-function-and-proc-macro-with-same-name

Rust: How to have function and `proc_macro` with same name

Primary LanguageRust

Rust: How to export a function and a proc_macro with same name

I was in the process of writing a macro helper when I realized that the macro might also be useful as a function for other proc_macro crates. But then I ran into the problem that is not possible to export both a proc_macro and a function from the same crate.

After searching did not give an answer, I decided to write down the solution here. In the end, I ended up defining a trait instead though :)

use proc_macro::TokenStream;

#[proc_macro]
pub fn foo(_: TokenStream) -> TokenStream {
    TokenStream::new()
}

pub fn foo() {}

The reason is that, while functions and macros don't share the same namespace, in a proc_macro crate the proc_macro is defined using a function with the same name.

In fact, it's not possible at all to export anything other than proc_macros, and will give the following error.

proc-macro crate types currently cannot export any items other than functions tagged with #[proc_macro], #[proc_macro_derive], or #[proc_macro_attribute]

After consulting the Rust Programming Language Community Discord, bendn suggested using a separate crate and re-exporting.

pub use foo_macro::foo;
pub fn foo() {}

Then you can use the top crate like this:

use foo::*;
foo();
foo!();

This repo contains the full example you can clone and verify.

git clone https://github.com/fredrik-hammar/rust-function-and-proc-macro-with-same-name.git
cd rust-function-and-proc-macro-with-same-name
cargo test