{"record":{"id":"f5a4dcf44912cfb7","repo":"GraphiteEditor/Graphite","slug":"expected-impl-implementation","errorCode":null,"errorMessage":"Expected impl implementation","messagePattern":"Expected impl implementation","errorType":"validation","errorClass":"syn::Error","httpStatus":null,"severity":"error","filePath":"proc-macros/src/message_handler_data_attr.rs","lineNumber":14,"sourceCode":"use crate::helpers::{call_site_ident, clean_rust_type_syntax};\nuse proc_macro2::{Span, TokenStream};\nuse quote::{ToTokens, quote};\nuse syn::{ItemImpl, Type, parse2, spanned::Spanned};\n\npub 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 {","sourceCodeStart":1,"sourceCodeEnd":32,"githubUrl":"https://github.com/GraphiteEditor/Graphite/blob/c507b356453361e31638b8bff8f6d46b6da2961e/proc-macros/src/message_handler_data_attr.rs#L1-L32","documentation":"The `#[message_handler_data]` attribute must be applied to a trait impl whose implementing (self) type is a plain type path like `MyHandler`. This error fires when the self type parses to something else (reference, tuple, slice, pointer, etc.), so the macro cannot extract the type identifier it needs for `MessageData` registration.","triggerScenarios":"Writing `#[message_handler_data] impl MessageHandler<M, C> for &MyType { … }` (reference self type), `for (A, B)` (tuple), or any non-path implementing type. The check is `**impl_block.self_ty` failing to match `Type::Path`.","commonSituations":"Implementing a handler on a reference or smart-wrapper type during a lifetime refactor, or applying the attribute to an impl block generated by a blanket impl over non-path types.","solutions":["Implement the trait directly for the named type: `impl MessageHandler<M, C> for MyType { … }`.","If the reference indirection is required, introduce a newtype wrapper and implement for that path.","Ensure the attribute sits on an `impl … for <path>` block, not on other items."],"exampleFix":"// before\n#[message_handler_data]\nimpl MessageHandler<ToolMessage, ToolMessageData> for &BrushTool { ... }\n\n// after\n#[message_handler_data]\nimpl MessageHandler<ToolMessage, ToolMessageData> for BrushTool { ... }","handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":["Implement MessageHandler for a plain named type (path), not references, tuples, or slices.","If indirection is needed, introduce a newtype path type.","Keep #[message_handler_data] only on `impl MessageHandler<…> for <Path>` blocks."],"tags":["rust","proc-macro","message-handler","impl-block","type-path"],"backgroundTag":"proc-macro-input-validation","analyzedSha":"c507b356453361e31638b8bff8f6d46b6da2961e","analyzedAt":"2026-08-16T21:57:18.596Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}