Skip to content

Using $crate with a proc macro #37637

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:

  • $crate is eliminated before invoking the proc macro, or
  • $crate is passed to the proc macro and can be parsed by TokenStream.
#!/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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions