Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to emit Rust attributes from within macros?

Tags:

macros

rust

I'm trying to do something like the following:

macro_rules! attr_trial {
    ($msg:expr) => {{
        let id = env!("SOME_ENV");

        #[link_section = env!("SOME_ENV")]
        static MESSAGE: &'static str = $msg;
    }};
}

And I get the following error:

error: unexpected token: `env`
  --> src/main.rs:34:18
   |
34 |            #[link_section = env!("SOME_ENV")]
   |                           ^
like image 534
Gilad Naaman Avatar asked Mar 10 '23 00:03

Gilad Naaman


1 Answers

Is it possible to emit Rust attributes from within macros?

Absolutely, it is possible. Here's a macro that emits a test attribute from within a macro:

macro_rules! example {
    () => {
        #[test]
        fn test() {
            assert!(false);
        }
    };
}

example!();

It's not possible in all contexts, however. For example, you can't emit just an attribute because the attribute is expected to be attached to an item:

macro_rules! example {
    () => {
        #[test]
    };
}

// Fails!
example!();
fn test() {
    assert!(false);
}

Your actual question is closer to "is it possible to call a macro inside of an attribute". The answer is yes, but only starting in Rust 1.54.

Before that version, the parser does not expect a macro expansion in that location. If you need it then, you might want to look at code generation or procedural macros, depending on what you are trying to do.

See answers on How is it possible to keep Rust module documentation in separate Markdown files? for more details.

like image 111
Shepmaster Avatar answered Mar 30 '23 00:03

Shepmaster