dtolnay / paste

Macros for all your token pasting needs
Apache License 2.0
1.02k stars 56 forks source link

`#[doc]` does not concat if a macro produces a literal string #99

Open chanced opened 1 year ago

chanced commented 1 year ago

I'm incredibly new to macros so I don't know if this is even possible to address.

If a macro that produces a string literal is used in #[doc], paste does not concat.

macro_rules! create_string {
    () => {
        "example"
    };
}
macro_rules! example {
    () => {
        paste::paste! {
            #[doc = create_string!() "example"]
            fn example(){}
        }
    };
}
error: expected one of `.`, `?`, `]`, or an operator, found `"example"`
  --> sandbox/src/lib.rs:20:38
   |
20 |             #[doc = create_string!() "example"]
   |                                      ^^^^^^^^^ expected one of `.`, `?`, `]`, or an operator
...
26 | example!();
Dantsz commented 6 months ago

~I don't think paste fits here, afaik the doc comment expects a &str, and the result of paste is an identifier~. I was wrong and it seems this is related to proc_macros expansion, and there is an unstable feature to expand macros that resolve to literals: https://github.com/rust-lang/rust/issues/90765 You can just use concat! here, which does eager macro expansion:

macro_rules! create_string {
    () => {
        "example"
    };
}
macro_rules! example {
    () => {
            #[doc = concat!(create_string!(), "a")]
            fn example(){}
    }
}

~You also would use [< >] if you wanted to create a new identifier, but I'm not sure if paste can expand macros.~