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

  1. Implement the trait directly for the named type: `impl MessageHandler<M, C> for MyType { … }`.
  2. If the reference indirection is required, introduce a newtype wrapper and implement for that path.
  3. 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

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


AI-assisted analysis of GraphiteEditor/Graphite@c507b35645 (2026-08-16). Data as JSON: /api/errors/f5a4dcf44912cfb7. Report an issue: GitHub.