neon-bindings/neon · error
Class export can only be applied to named types
Error message
Class export can only be applied to named types
What it means
The class export macro only supports impls whose self type is a named path type (syn::Type::Path). Any other type form — references, tuples, slices, trait objects, pointers, etc. — is rejected with this message at the self type span.
Solutions
- Apply the export only to a concrete named struct/enum: `impl MyType { ... }`
- Remove `&`, `Box`, `dyn Trait`, or other wrappers from the self type
- If exporting is not intended, drop the #[neon] export attribute from that impl
Example fix
// before
#[neon]
impl dyn Greet { // not a named type
fn new(cx: &mut FunctionContext) -> JsResult<JsGreet> { ... }
}
// after
#[neon]
impl Greet {
fn new(cx: &mut FunctionContext) -> JsResult<JsGreet> { ... }
} Defensive patterns
Strategy: type-guard
Type guard
// reject reference, tuple, slice, and trait-object self types
fn is_exportable_self_type(ty: &syn::Type) -> bool {
matches!(ty, syn::Type::Path(p) if p.qself.is_none() && !p.path.segments.is_empty())
} Prevention
- Only mark impls of concrete named types with #[neon] export
- Strip `&`, `Box`, and `dyn Trait` wrappers before exporting
- Keep export attributes off internal/helper impl blocks
When it happens
Trigger: Writing #[neon] export on an `impl` for a non-path self type such as `impl &T`, `impl Box<T> as ...` malformed forms, `impl dyn Trait`, `impl [T]`, or `impl ()`.
Common situations: Trying to export a trait object or reference type; accidentally exporting an impl block intended for internal use; typos producing non-path types like extra `&` or parentheses.
Understand the failure class
Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.
Related errors
- Expected type name
- Expected an owned `Channel` instead of a context reference.
- Context is not available in async functions. Try a…
- Expected a context argument after `&self` when using…
- Unexpected second receiver argument.
AI-assisted analysis of neon-bindings/neon@38960e4381 (2026-09-13).
Data as JSON: /api/errors/7c0201adaae65a0d.
Report an issue: GitHub.
Appendix: source
Thrown at crates/neon-macros/src/export/class.rs:89
#class_tokens
#create_fn
)
.into()
}
// Extract the class identifier from an impl block
fn extract_class_ident(input: &syn::ItemImpl) -> syn::Result<syn::Ident> {
match &*input.self_ty {
syn::Type::Path(syn::TypePath {
path: syn::Path { segments, .. },
..
}) => {
let syn::PathSegment { ident, .. } = segments
.last()
.ok_or_else(|| syn::Error::new(input.self_ty.span(), "Expected type name"))?;
Ok(ident.clone())
}
_ => Err(syn::Error::new(
input.self_ty.span(),
"Class export can only be applied to named types",
)),
}
}
View on GitHub (pinned to 38960e4381)