Skip to content

$crate unexpectedly disintegrates depending on unrelated macro invocations #57089

Closed
@dtolnay

Description

@dtolnay

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.

  • Either we need to find out what is causing $crate to disintegrate into $ + crate and stop that from happening (preferred),
  • Or the parser needs to accept an appropriately spanned $ + crate where it appears in procedural macro output.

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)

Metadata

Metadata

Assignees

Labels

A-macrosArea: All kinds of macros (custom derive, macro_rules!, proc macros, ..)C-bugCategory: This is a bug.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions