24
votes

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.

3
1. Is your procedural macro really generating a struct and not an impl block? For dumb reasons, the most reliable approach is way more complicated for macros that generate a struct compared to macros that generate an impl.dtolnay
2. Is this for a proc_macro_derive macro, or a different type of procedural macro?dtolnay
3. [SomeTrait; #len] is not a thing you can do, because [T; n] requires T: Sized. See play.rust-lang.org/?gist=bb33e5ba42a7e64af998b014483329f0. Can you clarify the intended result?dtolnay
@dtolnay: 1. It's generating a struct and an impl block. 2. This is for Nightly Macros 2.0 ; 3. Something like play.rust-lang.org/… (I need procedural macros, since I want to parse first parameter in specific way)Daniel Fath
@dtolnay Updated questions with clarification.Daniel Fath

3 Answers

4
votes

Based on replies from https://github.com/rust-lang/rust/issues/38356#issuecomment-412920528, it looks like there is no way to do this (as of 2018-08), neither to refer to the proc-macro crate nor to refer to any other crate unambiguously.

3
votes

Since Rust 1.34, you can use extern crate self as my_crate, and use my_crate::Foo instead of $crate::Foo.

https://github.com/rust-lang/rust/issues/54647

https://github.com/rust-lang/rust/pull/57407

(Credit: Neptunepink ##rust irc.freenode.net)

2
votes

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.