{"record":{"id":"1efe2579d5676a22","repo":"GraphiteEditor/Graphite","slug":"expected-type-path","errorCode":null,"errorMessage":"Expected type path","messagePattern":"Expected type path","errorType":"validation","errorClass":"syn::Error","httpStatus":null,"severity":"error","filePath":"proc-macros/src/message_handler_data_attr.rs","lineNumber":72,"sourceCode":"\t\t\t\t\t\t\t\t\t\t\tMessageData::new(format!(\"{}\", stringify!(#input_type)), #input_type::field_types(), #input_type::path(), #input_type::line_number())\n\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tsyn::Type::Tuple(_) => quote! {\n\t\t\t\t\t\t\t\t#input_item\n\t\t\t\t\t\t\t\timpl #message_type {\n\t\t\t\t\t\t\t\t\t\tpub fn message_handler_str() -> MessageData {\n\t\t\t\t\t\t\t\t\t\t\tMessageData::new(format!(\"{}\", stringify!(#input_type)), #input_type::field_types(), #input_type::path(), #input_type::line_number())\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tsyn::Type::Reference(type_reference) => {\n\t\t\t\t\t\t\t\tlet message_type = call_site_ident(format!(\"{input_type}Message\"));\n\t\t\t\t\t\t\t\tlet type_ident = match &*type_reference.elem {\n\t\t\t\t\t\t\t\t\tsyn::Type::Path(type_path) => &type_path.path.segments.first().unwrap().ident,\n\t\t\t\t\t\t\t\t\t_ => return Err(syn::Error::new(type_reference.elem.span(), \"Expected type path\")),\n\t\t\t\t\t\t\t\t};\n\n\t\t\t\t\t\t\t\tlet type_line_number = type_ident.span().start().line;\n\n\t\t\t\t\t\t\t\tlet tr = clean_rust_type_syntax(type_reference.to_token_stream().to_string());\n\t\t\t\t\t\t\t\tquote! {\n\t\t\t\t\t\t\t\t\t#input_item\n\t\t\t\t\t\t\t\t\timpl #message_type {\n\t\t\t\t\t\t\t\t\t\tpub fn message_handler_data_str() -> MessageData {\n\t\t\t\t\t\t\t\t\t\t\tMessageData::new(format!(\"{}\", #tr), #type_ident::field_types(), #type_ident::path(), #type_ident::line_number())\n\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\tpub fn message_handler_str() -> MessageData {\n\t\t\t\t\t\t\t\t\t\t\tMessageData::new(format!(\"{}\", stringify!(#input_type)), #input_type::field_types(), #input_type::path(), #input_type::line_number())\n\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}","sourceCodeStart":54,"sourceCodeEnd":90,"githubUrl":"https://github.com/GraphiteEditor/Graphite/blob/c507b356453361e31638b8bff8f6d46b6da2961e/proc-macros/src/message_handler_data_attr.rs#L54-L90","documentation":"Inside `#[message_handler_data]`, when the context type argument `C` of `MessageHandler<M, C>` is a reference (`&T` / `&'a mut T`), the referenced element must itself be a plain type path so the macro can take its identifier for line-number lookup and `field_types()`/`path()` calls. A reference to a tuple, slice, or other non-path type fails here.","triggerScenarios":"Writing `impl MessageHandler<Msg, &(u8, u8)> for …`, `impl MessageHandler<Msg, &[Tool]…>` style reference-to-non-path context types. The match binds `Type::Reference` but the inner `elem` is not `Type::Path`.","commonSituations":"Changing a context parameter from a named data struct to an ad-hoc tuple or slice reference to 'simplify' a handler signature, especially for tools that previously shared a single context struct.","solutions":["Use a named struct (or the conventional ToolMessageData type) as the referenced context: `&ToolMessageData`.","Define `struct Ctx(u8, u8);` and use `&Ctx` so the inner element is a path.","If the tuple form was intentional, use a plain tuple type `C = (u8, u8)` rather than a reference to one — the macro has a dedicated arm for tuple context types."],"exampleFix":"// before\n#[message_handler_data]\nimpl MessageHandler<BrushMessage, &(u64, String)> for BrushTool { ... }\n\n// after\nstruct BrushContext {\n\tlayer: u64,\n\tname: String,\n}\n#[message_handler_data]\nimpl MessageHandler<BrushMessage, &BrushContext> for BrushTool { ... }","handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use `&NamedStruct` (reference to a path) as the context type, never a reference to a tuple/slice.","Introduce a named context struct for multi-field contexts."],"tags":["rust","proc-macro","message-handler","reference-type","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"}