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

  1. Apply the export only to a concrete named struct/enum: `impl MyType { ... }`
  2. Remove `&`, `Box`, `dyn Trait`, or other wrappers from the self type
  3. 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

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


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)