{"record":{"id":"45a6261fe988dbf3","repo":"neon-bindings/neon","slug":"class-must-be-implemented-for-a-type-name","errorCode":null,"errorMessage":"class must be implemented for a type name","messagePattern":"class must be implemented for a type name","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/neon-macros/src/class/mod.rs","lineNumber":847,"sourceCode":"    _attr: proc_macro::TokenStream,\n    item: proc_macro::TokenStream,\n    custom_class_name: Option<String>,\n) -> proc_macro::TokenStream {\n    let mut impl_block = syn::parse_macro_input!(item as syn::ItemImpl);\n\n    // Parse the item as an implementation block\n    let syn::ItemImpl { self_ty, items, .. } = impl_block.clone();\n\n    let class_ident = match *self_ty {\n        syn::Type::Path(syn::TypePath {\n            path: syn::Path { segments, .. },\n            ..\n        }) => {\n            let syn::PathSegment { ident, .. } = segments.last().unwrap();\n            ident.clone()\n        }\n        _ => {\n            panic!(\"class must be implemented for a type name\");\n        }\n    };\n    let class_name = custom_class_name.unwrap_or_else(|| class_ident.to_string());\n\n    // Group the items into `const` and `fn` categories\n    let ClassItems {\n        consts,\n        fns,\n        constructor,\n        has_finalizer,\n    } = match group_class_items(items.clone()) {\n        Ok(items) => items,\n        Err(err) => {\n            // If sorting fails, return the error as a compile error\n            return err.to_compile_error().into();\n        }\n    };\n","sourceCodeStart":829,"sourceCodeEnd":865,"githubUrl":"https://github.com/neon-bindings/neon/blob/38960e4381d9ad13b551cdf2d261f609167c9bc2/crates/neon-macros/src/class/mod.rs#L829-L865","documentation":"The `#[neon::class]` (class_with_name) attribute macro only supports being applied to a struct/enum type definition whose name is the class type. When the macro expands it inspects the last path segment of the annotated item to derive the class name; if the item is anything other than a simple type name (e.g. a function, tuple struct with anonymous fields, impl block, or complex path) the macro panics with this message instead of compiling gracefully.","triggerScenarios":"Applying `#[neon::class]` to a non-type item (a fn, mod, impl, or trait); applying it to a unit/tuple struct where no nameable ident can be extracted; using the macro on a re-exported or path-qualified type instead of a locally defined named struct.","commonSituations":"Copy-pasting the attribute onto the wrong item; trying to register an existing imported type (only locally defined types work); refactoring a named struct into a tuple struct and forgetting to move the attribute; applying macros in bulk across a module.","solutions":["Move `#[neon::class]` so it sits directly on a named struct (or enum) definition.","Ensure the type is a unit/named struct with an explicit identifier, e.g. `struct Greeter { ... }`, not a tuple or unit struct.","If wrapping an imported type, define a new named wrapper struct in your crate and annotate that instead.","Remove the macro from any fn/impl/mod items it was accidentally attached to."],"exampleFix":"// before\n#[neon::class]\nfn make_greeter() -> Greeter { Greeter }\n\n// after\n#[neon::class]\nstruct Greeter { /* fields */ }","handlingStrategy":"validation","validationCode":"// attach the macro only to named structs/enum types\n#[neon::class]\nstruct Greeter { /* named fields */ }\n// sanity check in review/CI: grep for #[neon::class] lines and confirm\n// the next non-attribute line starts with `struct` or `enum`","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never place #[neon::class] on functions, impls, or modules","Only annotate locally defined named types, not imports or tuple structs","Keep macro and its target adjacent; avoid bulk-annotating with macro_rules"],"tags":["rust","macros","neon","compile-time"],"backgroundTag":"invalid-argument-value","analyzedSha":"38960e4381d9ad13b551cdf2d261f609167c9bc2","analyzedAt":"2026-09-13T09:05:33.640Z","contentChangedAt":"2026-09-13T09:05:33.640Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}