Search code examples
rustrust-proc-macrosrust-attributes

error: `cannot find attribute in this scope` when using custom proc_macro with attributes written with darling in rust


I am writing a library which includes a custom derive macro with custom attributes. For this I use darling. My project structure, thus, is as follows:

├── pg-worm
│   ├── pg-worm-derive
│   │   ├── src/lib.rs
│   ├── src/lib.rs

My proc macro is specified like this (pg-worm/pg-worm-derive/src/lib.rs):

use darling::FromDeriveInput;
use proc_macro::{self, TokenStream};
use syn::parse_macro_input;

#[derive(FromDeriveInput)]
#[darling(attributes(table))]
ModelInput {
    table_name: Option<String>
}

#[proc_macro_derive(Model)]
pub fn derive(input: TokenStream) -> TokenStream {
    let opts = ModelInput::from_derive_input(&parse_macro_input!(input)).unwrap();

    // macro magic happens
}

And then I reexport the macro from my main file (pg-worm/src/lib.rs):

pub use pg_worm_derive::*;

pub trait Model {
    // trait specs
}

But when I test my macro using the following code (in pg-worm/src/lib.rs too):

#[cfg(test)]
mod tests {
    use pg_worm::Model;

    #[derive(Model)]
    #[table(table_name = "person")]
    struct Person {
        id: i64,
        name: String,
    }
}

I get the following error upon cargo test:

error: cannot find attribute `table` in this scope
  --> src/lib.rs:96:7
   |
96 |     #[table(table_name = "person")]
   |       ^^^^^ help: a built-in attribute with a similar name exists: `stable`

error: could not compile `pg-worm` due to previous error

It works when I skip using the table attribute, so the macro itself does seem to work. Why isn't the attribute working? Do I need to do some extra reexporting?


Solution

  • You need to specify that #[table] is a helper attribute of #[derive(Model)]:

    #[proc_macro_derive(Model, attributes(table))]
    pub fn derive(input: TokenStream) -> TokenStream { ... }