{"record":{"id":"a6b3bc69d8dee1cc","repo":"GraphiteEditor/Graphite","slug":"tried-to-derive-asmessage-for-non-enum","errorCode":null,"errorMessage":"Tried to derive AsMessage for non-enum","messagePattern":"Tried to derive AsMessage for non-enum","errorType":"validation","errorClass":"syn::Error","httpStatus":null,"severity":"error","filePath":"proc-macros/src/as_message.rs","lineNumber":9,"sourceCode":"use proc_macro2::{Span, TokenStream};\nuse syn::{Data, DeriveInput};\n\npub fn derive_as_message_impl(input_item: TokenStream) -> syn::Result<TokenStream> {\n\tlet input = syn::parse2::<DeriveInput>(input_item).unwrap();\n\n\tlet data = match input.data {\n\t\tData::Enum(data) => data,\n\t\t_ => return Err(syn::Error::new(Span::call_site(), \"Tried to derive AsMessage for non-enum\")),\n\t};\n\n\tlet input_type = input.ident;\n\n\tlet (globs, names) = data\n\t\t.variants\n\t\t.iter()\n\t\t.map(|var| {\n\t\t\tlet var_name = &var.ident;\n\t\t\tlet var_name_s = var.ident.to_string();\n\t\t\tif var.attrs.iter().any(|a| a.path().is_ident(\"child\")) {\n\t\t\t\t(\n\t\t\t\t\tquote::quote! {\n\t\t\t\t\t\t#input_type::#var_name(child)\n\t\t\t\t\t},\n\t\t\t\t\tquote::quote! {\n\t\t\t\t\t\tformat!(\"{}.{}\", #var_name_s, child.local_name())\n\t\t\t\t\t},","sourceCodeStart":1,"sourceCodeEnd":27,"githubUrl":"https://github.com/GraphiteEditor/Graphite/blob/c507b356453361e31638b8bff8f6d46b6da2961e/proc-macros/src/as_message.rs#L1-L27","documentation":"The AsMessage derive (proc-macros/src/as_message.rs) only generates code for enums — it builds per-variant globs and #[child]-aware handling. Applying the derive to a struct or union falls through the Data::Enum match and yields this compile-time error at the call site.","triggerScenarios":"#[derive(AsMessage)] (or a derive chain that includes it) placed on a struct or union instead of an enum.","commonSituations":"Refactoring an enum message type into a struct during cleanup while the derive stays attached; adding the derive via IDE quick-fix on the wrong item.","solutions":["Remove the AsMessage derive from the struct or union","Convert the type to an enum if it must participate in the message hierarchy (variants may carry #[child])","Hand-implement the trait if the struct genuinely must remain a struct"],"exampleFix":"// before\n#[derive(AsMessage)]\nstruct MyMessage { field: u32 }\n\n// after\n#[derive(AsMessage)]\nenum MyMessage {\n\t#[child]\n\tVariantOne(u32),\n\tVariantTwo,\n}","handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":["AsMessage is enum-only — check the item kind before attaching the derive","Keep message types as enums in this codebase","After refactors, compile immediately so a misplaced derive fails fast"],"tags":["proc-macro","rust","derive","compile-time"],"backgroundTag":"derive-on-non-enum","analyzedSha":"c507b356453361e31638b8bff8f6d46b6da2961e","analyzedAt":"2026-08-16T21:57:18.596Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}