3

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"]
   |   ^^^^^^^
Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
flying sheep
  • 8,475
  • 5
  • 56
  • 73

1 Answers1

4

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.

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
  • Interesting. I'm sure I imported `pest::Parser` at some point, which should be identical to `pest_derive::Parser`. So you have to import the trait from the crate implementing the derive? – flying sheep Oct 30 '18 at 23:16
  • @flyingsheep *which should be identical to `pest_derive::Parser`* — it is not, no more than `crate1::Parser` is the same as `crate2::Parser`. *import the trait from the crate implementing the derive* — no, you import the derive macro `Parser` from the crate implementing the macro; you probably also have to import the trait `Parser` from the main crate as well. – Shepmaster Oct 30 '18 at 23:48
  • Got it! That's a bit confusing if you think in names: “I've already imported a thing called `Parser`, I shouldn't have to do it twice” – flying sheep Oct 31 '18 at 07:10