Exporting attribute macros

Is it currently possible to A) export an attribute macro from a proc-macro crate and then B) use the attribute macro to generate code?

Question B appears to be a "yes", but with A, I am still uncertain. I get compile errors when I try to import an attribute-macro from an adjacent crate that has a proc-macro = true in the cargo.toml.

In the crate which uses the attribute macro, I have #[macro_use] extern crate my_derive_crate as normally required.

I'm not clear on what isn't working. Could you make a minimal github repo or gist with the source files, Cargo.toml, and error message?

The precise word you mean, I think, is reexport-ing a (proc-)macro. As with any macro, this is not done with #[macro_use] extern crate foo but with pub use:

// reexports `bar!`
pub use ::foo::{
   bar,
};

Thanks for the replies y'all.

This snippet is in the my_derive crate's lib.rs:

#[proc_macro]
pub fn runtime(_item: TokenStream) -> TokenStream {
     "println!(\"Hello World from runtime macro! \");".parse().unwrap()
}

and then in the accessing crate's lib.rs:

pub use ::my_derive::runtime;

and then in an arbitrary source file inside the accessing crate:

#[runtime]
fn start() {
    //This should print out "hello world [...]!"
}

Maybe you guys see what I'm trying to do now, as language can be a barrier for me. And, this compiles, but i don't get any console print-out when i execute start()

I still can't tell what is going on entirely, but the runtime function you show is not an attribute macro. Attributes macros start with #[proc_macro_attribute] and have a different signature. Would you be able to show more of the relevant code or toss a minimal project on github that reproduces the behavior you are describing?

1 Like

Solved:

I had to do this:

#[proc_macro_attribute]
pub fn runtime(attr: TokenStream, item: TokenStream) -> TokenStream {
    
    /*println!("attr: \"{}\"", attr.to_string());
    println!("item: {}", item.to_string());
    */

    let raw = item.to_string();
    let mut parts = raw.splitn(4, " ").collect::<Vec<&str>>();

    if parts[0] != "fn" || parts.len() != 4 {
        panic!("Invalid runtime function formatting!");
    }

    let insert = "println!(\"Hello World from runtime macro! \");";

    let ret = parts[0].to_owned()  + " " + parts[1] + " " + parts[2] + " " + insert + " " + parts[3];

    TokenStream::from_str(ret.as_str()).unwrap()
}

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.