英文:
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?
英文:
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?
答案1
得分: 4
#[proc_macro_derive(Model, attributes(table))]
pub fn derive(input: TokenStream) -> TokenStream { ... }
英文:
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 { ... }
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论