GraphiteEditor/Graphite · error · syn::Error
Expected impl implementation
Error message
Expected impl implementation
What it means
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.
Source
Thrown at proc-macros/src/message_handler_data_attr.rs:14
use crate::helpers::{call_site_ident, clean_rust_type_syntax};
use proc_macro2::{Span, TokenStream};
use quote::{ToTokens, quote};
use syn::{ItemImpl, Type, parse2, spanned::Spanned};
pub fn message_handler_data_attr_impl(attr: TokenStream, input_item: TokenStream) -> syn::Result<TokenStream> {
// Parse the input as an impl block
let impl_block = parse2::<ItemImpl>(input_item.clone())?;
let self_ty = &impl_block.self_ty;
let path = match &**self_ty {
Type::Path(path) => &path.path,
_ => return Err(syn::Error::new(Span::call_site(), "Expected impl implementation")),
};
let input_type = path.segments.last().map(|s| &s.ident).unwrap();
let handler_line_number = input_type.span().start().line;
// Extract the message type from the trait path
let trait_path = match &impl_block.trait_ {
Some((_, path, _)) => path,
None => return Err(syn::Error::new(Span::call_site(), "Expected trait implementation")),
};
// Get the trait generics (should be MessageHandler<M, C>)
if let Some(segment) = trait_path.segments.last() {
if segment.ident != "MessageHandler" {
return Err(syn::Error::new(segment.ident.span(), "Expected MessageHandler trait"));
}
if let syn::PathArguments::AngleBracketed(args) = &segment.arguments {View on GitHub (pinned to c507b35645)
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.
Example fix
// before
#[message_handler_data]
impl MessageHandler<ToolMessage, ToolMessageData> for &BrushTool { ... }
// after
#[message_handler_data]
impl MessageHandler<ToolMessage, ToolMessageData> for BrushTool { ... } Defensive patterns
Strategy: validation
Prevention
- 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.
When it happens
Trigger: 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`.
Common situations: 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.
Related errors
- Expected type path
- Expected trait implementation
- Expected MessageHandler trait
- Unsupported type format
- Failed to parse input type for #[implementation(...)]. Expec
AI-assisted analysis of GraphiteEditor/Graphite@c507b35645 (2026-08-16).
Data as JSON: /api/errors/f5a4dcf44912cfb7.
Report an issue: GitHub.