syskov
syskov

Reputation: 86

Unable to get field attrs with syn/darling

I am trying to get field attributes in a proc-macro with syn/darling crates. Here is a MRE

Cargo.toml

[package]
name = "darling_attrs"
version = "0.1.0"
edition = "2018"

[lib]
proc-macro = true

[dependencies]
darling = "0.10"
proc-macro2 = "1.0"
quote = "1.0"
syn = { version = "1.0", features = ["full"] }

src/lib.rs

extern crate proc_macro;
extern crate proc_macro2;

mod cat;

use proc_macro::TokenStream;
use syn::DeriveInput;

#[proc_macro_derive(Cat)]
pub fn derive_cat(input: TokenStream) -> TokenStream {
    let input = syn::parse_macro_input!(input as DeriveInput);
    cat::expand_derive_cat(&input)
}

src/cat.rs

use darling::{FromField, FromDeriveInput};
use proc_macro::TokenStream;
use quote::{ToTokens, quote};

#[derive(Clone, Debug, FromField)]
struct StructField {
    ident: Option<syn::Ident>,
    ty: syn::Type,
    vis: syn::Visibility,
    // If the line would be commented, all will be fine
    attrs: Vec<syn::Attribute>,
}

#[derive(Debug, FromDeriveInput)]
#[darling(supports(struct_named))]
struct Cat {
    ident: syn::Ident,
    data: darling::ast::Data<(), StructField>,
}

impl ToTokens for Cat {
    fn to_tokens(&self, out: &mut proc_macro2::TokenStream) {
        let tokens = quote!{};

        let fields = self.data.clone().take_struct().unwrap();

        //dbg!(fields);

        out.extend(tokens)
    }
}

pub fn expand_derive_cat(input: &syn::DeriveInput) -> TokenStream {
    let cat = match Cat::from_derive_input(&input) {
        Ok(parsed) => parsed,
        Err(e) => return e.write_errors().into(),
    };

    let tokens = quote! { #cat };
    tokens.into()
}

But the error is thrown

error[E0425]: cannot find value `__fwd_attrs` in this scope
 --> src/cat.rs:5:24
  |
5 | #[derive(Clone, Debug, FromField)]
  |                        ^^^^^^^^^ not found in this scope

error: aborting due to previous error

For more information about this error, try `rustc --explain E0425`.
error: could not compile `darling_attrs`.

To learn more, run the command again with --verbose.

If line 11 at cat.rs(I've marked it with comment) would be commented, programm will compile without errors.

Here is impl FromField for Vec. As I understand, there is some problem with this code But I have no idea how to fix that.

How can I have a field attrs on my StructField::attrs?

Upvotes: 4

Views: 1471

Answers (1)

Frank
Frank

Reputation: 61

You miss 'forward_attrs' by struct 'StructField' as described in the crate documentation.

For example:

#[derive(Clone, Debug, FromField)]
#[darling(forward_attrs(cfg)]
struct StructField {
    ident: Option<syn::Ident>,
    ty: syn::Type,
    vis: syn::Visibility,
    // If the line would be commented, all will be fine
    attrs: Vec<syn::Attribute>,
}

Upvotes: 2

Related Questions