Search code examples
macrosrustrust-macros

Why does importing a custom derive Foo via `use some_crate::derive_foo` not work?


I want to use a custom derive macro that uses attributes. For Rust 2015, I wrote:

#[macro_use]
extern crate pest_derive;

#[derive(Parser)]
#[grammar = "grammar.pest"]
pub struct MyParser;

Using edition = '2018', extern crate is deprecated so macro_use is unavailable. I assumed I could write use pest_derive::{grammar,derive_parser};, but I have to write use pest_derive::*;.

How can I avoid the glob import? The code for the pest_derive crate is very simple, I have no idea what necessary thing * imports that isn’t derive_parser or grammar.

error[E0658]: The attribute `grammar` is currently unknown to the compiler and
              may have meaning added to it in the future (see issue #29642)
  --> src/parser/mod.rs:10:3
   |
10 | #[grammar = "rst.pest"]
   |   ^^^^^^^

Solution

  • That's the incorrect syntax for importing the derive. You import the name of the derive, not the underlying function. In this case, use pest_derive::Parser:

    use pest_derive::Parser;
    
    #[derive(Parser)]
    #[grammar = "grammar.pest"]
    pub struct MyParser;
    

    or

    #[derive(pest_derive::Parser)]
    #[grammar = "grammar.pest"]
    pub struct MyParser;
    

    This question isn't specific to Rust 2018, either. Rust 1.30 and up allows you to import macros like this.