Search code examples
rustrust-macros

Rust export proc_macro function not in the root of the crate


I've got a pretty big procedural macro crate. Right now everything is included in the src/lib.rs file. To make things more readable I would like to move components into their own file. However, I'm running into trouble when defining the #[proc_macro] functions. Is it possible, and if so how, to move exported #[proc_macro] functions outside the root of the crate?

The project structure is as following

 - Cargo.lock
 - Cargo.toml
 - src
    - lib.rs
    - module_file.rs

lib.rs

use proc_macro::TokenStream;

mod module_file;

#[proc_macro]
pub use module_file::some_function;

module_file.rs

use proc_macro::TokenStream;

pub fn some_function(tokens: TokenStream) -> TokenStream { ... }

This does not compile however. I get the following error:

error: the #[proc_macro] attribute may only be used on bare functions


Solution

  • Currently1 you have to define the actual function in the root lib.rs, but it can be a thin shell just calling the actual implementation:

    use proc_macro::TokenStream;
    mod module {
        use proc_macro::TokenStream;
        pub(crate) fn some_function(t: TokenStream) -> TokenStream { t }
    }
    
    #[proc_macro]
    pub fn some_function(t: TokenStream) -> TokenStream {
        module::some_function(t)
    }
    

    1. that's what the compiler tells us anyways: error: functions tagged with `#[proc_macro]` must currently reside in the root of the crate.