0

I was trying a simple procedural macro following the example from the documentation, more specifically:

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

It shows how this macro prepends the function with the two prints. However, I've tried to reproduce an even simpler case, with my macro being:

#[proc_macro_attribute]
pub fn test_macro(_: TokenStream, item: TokenStream) -> TokenStream {
    println!("Macro start");
    item
}

I then run my main function of the crate:

use test_macro::test_macro;

#[test_macro]
fn main() {
    println!("yup");
}

And no prints appear. I thought maybe the main method can't have macros attached, so I tested on another function and it didn't work either. I'm pretty confused, what am I missing?

Dominus
  • 808
  • 11
  • 25
  • It seems to me this happens because I'm actually not modifying the `stream`, however in that case I believe the documentation is either wrong or outdated? – Dominus Jun 19 '21 at 06:48

1 Answers1

2

Writing to stdout in a procedural macro will do so at compile time, like the docs accurately state:

This following example shows the stringified TokenStreams that the attribute macros see. The output will show in the output of the compiler.

As you noticed, you need to return a TokenStream with the desired output of your macro. To do this you would typically use the syn and quote libraries, which allow you to parse and transform input and create new TokenStreams easily with the quote macro.

syn in particular has a few examples, for an attribute macro take a look at trace-var.

F0X
  • 370
  • 4
  • 13