quickwit-oss/quickwit · error · proc-macro compile error

the attribute can only be applied to struct

Error message

the attribute can only be applied to struct

What it means

serde_multikey is a proc-macro attribute that only makes sense on a struct declaration. serde_multikey_inner parses its input token stream as syn::ItemStruct and, if parsing fails (the item is an enum, union, fn, etc.), emits this compile error at the call site.

Source

Thrown at quickwit/quickwit-macros/src/lib.rs:37

use quote::quote;
use syn::parse::{Parse, ParseStream, Parser};
use syn::punctuated::Punctuated;
use syn::{
    Attribute, Error, Field, Fields, FieldsNamed, Ident, ItemStruct, Meta, Path, Token, Visibility,
    parenthesized,
};

#[proc_macro_attribute]
pub fn serde_multikey(attr: TokenStream, item: TokenStream) -> TokenStream {
    match serde_multikey_inner(attr, item) {
        Ok(ts) => ts,
        Err(e) => e.to_compile_error().into(),
    }
}

fn serde_multikey_inner(_attr: TokenStream, item: TokenStream) -> Result<TokenStream, Error> {
    let Ok(input) = syn::parse::<ItemStruct>(item) else {
        return Err(Error::new(
            Span::call_site(),
            "the attribute can only be applied to struct",
        ));
    };

    let main_struct = generate_main_struct(input.clone())?;

    let proxy_struct = generate_proxy_struct(input)?;

    Ok(quote!(
    #main_struct
    #proxy_struct
    )
    .into())
}

/// Generate the main struct. It's a copy of the original struct, but with most
/// ser/de attributes removed, and serde try_from/into `__MultiKey{}` added.

View on GitHub (pinned to a39730c5cd)

Solutions

  1. Move the #[serde_multikey] attribute onto the struct declaration that should gain multi-key serde behavior.
  2. If the target should be an enum, do not use serde_multikey; use plain serde derives instead.

Example fix

// before
#[serde_multikey(fields(key))]
enum KeyKind { A }
// after
#[derive(Serialize, Deserialize)]
#[serde_multikey(fields(key))]
struct KeyKind { key: String }
Defensive patterns

Strategy: validation

Validate before calling

// Compile-time guard: the macro only accepts structs.
// Verify the target is a struct before adding the attribute:
// struct MyStruct { ... }  // <-- attribute goes here, never on enum/fn/alias

Prevention

When it happens

Trigger: Applying #[serde_multikey(...)] to any non-struct item: an enum, type alias, function, module, or impl block.

Common situations: Developer intends a multi-key struct but attaches the attribute to the wrong item in the file, or applies it above a module/enum during refactoring.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of quickwit-oss/quickwit@a39730c5cd (2026-09-08). Data as JSON: /api/errors/1693348bdd308802. Report an issue: GitHub.