syn: syn::ItemStruct not found in syn

I have the following macro to get field names which are don’t have none values.

fn path_is_not_none(path: &Path) -> bool {
        path.leading_colon.is_none()
        && path.segments.len() == 1
        && path.segments.iter().next().unwrap().ident != "None"
}

#[proc_macro_derive(NotNoneFields)]
pub fn non_none_fields(input: TokenStream) -> TokenStream {
    let input = parse_macro_input!(input as syn::ItemStruct);

    let name = &input.ident;

    let mut field_names: Vec<String> = Vec::new();
    for field in input.fields.iter() {
        match &field.ty {
            Type::Path(typepath) if typepath.qself.is_none() && path_is_not_none(&typepath.path) => {
                field_names.push(stringify!(field.ident).to_string());
            },
            _ => (),
        }
    }

    let output = quote! {
        impl #name {
            pub fn not_none_fields() -> Vec<String>{
                #(field_names)
            }
        }
    };

    TokenStream::from(output)
}

After testing the code I get the following error:

  --> src/lib.rs:17:20
   |
17 |     let item: syn::ItemStruct = syn::parse(input).expect("failed to parse input");
   |                    ^^^^^^^^^^ not found in `syn`

error[E0412]: cannot find type `ItemStruct` in crate `syn`
  --> src/lib.rs:19:48
   |
19 |     let inp = parse_macro_input!(item as &syn::ItemStruct);
   |                                                ^^^^^^^^^^ not found in `syn`

error[E0412]: cannot find type `ItemStruct` in crate `syn`
  --> src/lib.rs:17:20
   |
17 |     let item: syn::ItemStruct = syn::parse(input).expect("failed to parse input");
   |                    ^^^^^^^^^^ not found in `syn`

error[E0412]: cannot find type `ItemStruct` in crate `syn`
  --> src/lib.rs:19:48
   |
19 |     let inp = parse_macro_input!(item as &syn::ItemStruct);
   |                                                ^^^^^^^^^^ not found in `syn`

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Comments: 21 (6 by maintainers)

Most upvoted comments

Thank you @taiki-e and @Robbepop

"expected one of ! or [, found (" error is about incorrect use of quote. #(field_names) is not a valid quote syntax and just treated as tokens. (see quote’s readme for correct syntax)

And field_names (a variable in proc-macro context) cannot be directly generated as Vec<String>, so #(field_names) should probably be something like this:

      let output = quote! {
          impl #name {
-             pub fn not_none_fields() -> Vec<String>{
-                 #(field_names)
+             pub fn not_none_fields() -> Vec<&'static str>{
+                 vec![#(#field_names),*]
              }
          }
      };

(Also, if you get unexpected errors when writing proc-macro (and if the macro itself has been successfully compiled), I’d recommend using cargo-expand to see what code is actually being generated.)