Using $crate in Rust's procedural macros?

Viewed 3655

I know what the $crate variable is, but as far as I can tell, it can't be used inside procedural macros. Is there another way to achieve a similar effect?

I have an example that roughly requires me to write something like this using quote and nightly Rust

quote!(
     struct Foo {
        bar: [SomeTrait;#len]
     }
)

I need to make sure SomeTrait is in scope (#len is referencing an integer outside the scope of the snippet).

I am using procedural macros 2.0 on nightly using quote and syn because proc-macro-hack didn't work for me. This is the example I'm trying to generalize.

4 Answers

In Edition 2015 (classic Rust), you can do this (but it's hacky):

  • use ::defining_crate::SomeTrait in the macro
  • within third-party crates depending on defining_crate, the above works fine
  • within defining_crate itself, add a module in the root:

    mod defining_crate { pub use super::*; }

In Edition 2018 even more hacky solutions are required (see this issue), though #55275 may give us a simple workaround.

You can wrap your proc-macro inside a declarative macro, and pass the $crate identifier to your proc-macro for reuse (see this commit for example). It will create a proc_macro::Ident value with the special $crate identifier.

Note that you cannot manually create such an identifier, since $ is normally invalid inside identifiers.

Related