Using $crate with a proc macro · Issue #37637 · rust-lang/rust (original) (raw)

Skip to content

Provide feedback

Saved searches

Use saved searches to filter your results more quickly

Sign up

Appearance settings

@dtolnay

Description

@dtolnay

It seems that TokenStream::parse() does not understand $crate, yet $crate gets passed as input to proc macros. That doesn't seem fair!

Here is a script to reproduce the issue. It creates a proc macro called noop_derive which just reparses the input TokenStream. It creates a crate called repro which uses #[derive(Noop)] from within macro_rules. Expected behavior would be either of the following:

#!/bin/bash

cargo new noop_derive cat >> noop_derive/Cargo.toml <<-'EOF' [lib] proc-macro = true EOF

cat > noop_derive/src/lib.rs <<-'EOF' #![feature(proc_macro, proc_macro_lib)]

extern crate proc_macro;
use proc_macro::TokenStream;

#[proc_macro_derive(Noop)]
pub fn noop(input: TokenStream) -> TokenStream {
    input.to_string().parse().unwrap()
}

EOF

cargo new repro cat >> repro/Cargo.toml <<-'EOF' noop_derive = { path = "../noop_derive" } EOF

cat > repro/src/lib.rs <<-'EOF' #![feature(proc_macro)]

#[macro_use]
extern crate noop_derive;

struct A;

macro_rules! B {
    () => {
        #[derive(Noop)]
        struct B {
            a: $crate::A
        }
    };
}

B!();

EOF

cd repro cargo build

$ ./repro.sh
     Created library `noop_derive` project
     Created library `repro` project
   Compiling noop_derive v0.1.0
   Compiling repro v0.1.0
error: custom derive attribute panicked
  --> src/lib.rs:10:22
   |
10 |             #[derive(Noop)]
   |                      ^^^^
...
17 |     B!();
   |     ----- in this macro invocation
   |
   = help: message: called `Result::unwrap()` on an `Err` value: LexError { _inner: () }

error: Could not compile `repro`.

To learn more, run the command again with --verbose.