$crate unexpectedly disintegrates depending on unrelated macro invocations · Issue #57089 · rust-lang/rust (original) (raw)

I have proc macros mac! which is function-like and #[attr] which is an attribute. Both of them simply emit their input unchanged (input.into_iter().collect()).

I have an invocation of both macros from another crate which passes tokens containing $crate. In the code below, everything is working as expected and both macros receive Ident { ident: "$crate" } in their input.

Now for the broken bit: I observed some spooky action at a distance in which changing the behavior of mac! affects the input of the totally unrelated invocation of #[attr]. The input of #[attr] decomposes into Punct { ch: '$' } + Ident { ident: "crate" } which rustc refuses to parse down the line.

repro_macros/src/lib.rs

extern crate proc_macro; use proc_macro::TokenStream;

#[proc_macro] pub fn mac(input: TokenStream) -> TokenStream { println!("MAC INPUT: {:#?}", input);

// Change this to `false` to observe the spooky effect on the input of #[attr].
if true {
    input.into_iter().collect()
} else {
    TokenStream::new()
}

}

#[proc_macro_attribute] pub fn attr(_args: TokenStream, input: TokenStream) -> TokenStream { println!("ATTR INPUT: {:#?}", input); input.into_iter().collect() }

repro/src/lib.rs

const UNIT: () = ();

macro_rules! m { () => { repro_macro::mac! { pub fn f() { $crate::UNIT } }

    #[repro_macro::attr]
    pub fn g() {
        $crate::UNIT
    }
};

}

m!();

Mentioning @petrochenkov since you worked on #56647.
Mentioning @alexcrichton.

rustc 1.33.0-nightly (2d3e909 2018-12-22)