{"record":{"id":"25ce541108821cfd","repo":"GraphiteEditor/Graphite","slug":"expected-trait-implementation","errorCode":null,"errorMessage":"Expected trait implementation","messagePattern":"Expected trait implementation","errorType":"validation","errorClass":"syn::Error","httpStatus":null,"severity":"error","filePath":"proc-macros/src/message_handler_data_attr.rs","lineNumber":24,"sourceCode":"pub fn message_handler_data_attr_impl(attr: TokenStream, input_item: TokenStream) -> syn::Result<TokenStream> {\n\t// Parse the input as an impl block\n\tlet impl_block = parse2::<ItemImpl>(input_item.clone())?;\n\n\tlet self_ty = &impl_block.self_ty;\n\n\tlet path = match &**self_ty {\n\t\tType::Path(path) => &path.path,\n\t\t_ => return Err(syn::Error::new(Span::call_site(), \"Expected impl implementation\")),\n\t};\n\n\tlet input_type = path.segments.last().map(|s| &s.ident).unwrap();\n\n\tlet handler_line_number = input_type.span().start().line;\n\n\t// Extract the message type from the trait path\n\tlet trait_path = match &impl_block.trait_ {\n\t\tSome((_, path, _)) => path,\n\t\tNone => return Err(syn::Error::new(Span::call_site(), \"Expected trait implementation\")),\n\t};\n\n\t// Get the trait generics (should be MessageHandler<M, C>)\n\tif let Some(segment) = trait_path.segments.last() {\n\t\tif segment.ident != \"MessageHandler\" {\n\t\t\treturn Err(syn::Error::new(segment.ident.span(), \"Expected MessageHandler trait\"));\n\t\t}\n\t\tif let syn::PathArguments::AngleBracketed(args) = &segment.arguments {\n\t\t\tif args.args.len() >= 2 {\n\t\t\t\t// Extract the message type (M) and context struct type (C) from the trait params\n\t\t\t\tlet message_type = &args.args[0];\n\t\t\t\tlet data_type = &args.args[1];\n\n\t\t\t\tlet impl_item = match data_type {\n\t\t\t\t\tsyn::GenericArgument::Type(t) => {\n\t\t\t\t\t\tmatch t {\n\t\t\t\t\t\t\tsyn::Type::Path(type_path) if !type_path.path.segments.is_empty() => {\n\t\t\t\t\t\t\t\t// Get just the base identifier (ToolMessageData) without generics","sourceCodeStart":6,"sourceCodeEnd":42,"githubUrl":"https://github.com/GraphiteEditor/Graphite/blob/c507b356453361e31638b8bff8f6d46b6da2961e/proc-macros/src/message_handler_data_attr.rs#L6-L42","documentation":"`#[message_handler_data]` must annotate a trait implementation, not an inherent impl. The macro reads the trait path from the impl block to extract the `MessageHandler<M, C>` generic arguments and generate the `MessageData` registration; an inherent `impl MyType { … }` has no trait to read, so the derive aborts.","triggerScenarios":"Applying the attribute to `impl ToolMessageData { … }` or any impl without a `for` clause / trait path. The match on `impl_block.trait_` returns None and errors.","commonSituations":"Adding helper methods to a handler struct and pasting the attribute on the wrong impl block, or annotating every impl in a file mechanically during integration of the message-handler system.","solutions":["Change the inherent impl into a trait impl: `impl MessageHandler<ToolMessage, ToolMessageData> for ToolMessageData { … }`.","Keep inherent helper methods in a separate, unannotated impl block.","Verify the trait generics are present; the macro expects MessageHandler<M, C> with two arguments."],"exampleFix":"// before\n#[message_handler_data]\nimpl ToolMessageData {\n\tfn tool_name(&self) -> String { ... }\n}\n\n// after\nimpl ToolMessageData {\n\tfn tool_name(&self) -> String { ... }\n}\n\n#[message_handler_data]\nimpl MessageHandler<ToolMessage, ToolMessageData> for ToolMessageData {\n\tfn process_message(&mut self, message: ToolMessage) { ... }\n}","handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":["Annotate only trait impls with #[message_handler_data]; leave inherent impls bare.","When adding helper methods, create a separate plain impl block."],"tags":["rust","proc-macro","message-handler","trait-impl"],"backgroundTag":"proc-macro-input-validation","analyzedSha":"c507b356453361e31638b8bff8f6d46b6da2961e","analyzedAt":"2026-08-16T21:57:18.596Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}