swc-project/swc · error

named enum unsupported

Error message

named enum unsupported

What it means

When expanding the #[encoding(unknown)] arm, the macro matches on unknown.fields and only handles syn::Fields::Unnamed; everything else — a named-field variant like `Unknown { tag: u32, value: Expr }` or a unit variant `Unknown` — falls into the catch-all and panics 'named enum unsupported'. The unknown variant must be positional: (tag) or (tag, value).

Source

Thrown at crates/ast_node/src/encoding/decode.rs:142

                                    tag => #ident::#name(tag),
                                }
                            }
                            2 => {
                                assert_eq!(enum_type, EnumType::One);
                                let val_ty = &fields.unnamed[1].ty;
                                syn::parse_quote! {
                                    tag => {
                                        let tag: u32 = tag.try_into().map_err(|_| cbor4ii::core::error::DecodeError::CastOverflow {
                                             name: &"unknown-tag",
                                        })?;
                                        let val = <#val_ty as cbor4ii::core::dec::Decode<'_>>::decode(reader)?;
                                        #ident::#name(tag, val)
                                    },
                                }
                            }
                            _ => panic!("unknown member must be a tag and a value"),
                        },
                        _ => panic!("named enum unsupported"),
                    }
                });

            if matches!(enum_type, EnumType::Struct) {
                assert!(
                    unknown_arm.is_none(),
                    "struct enum does not allow unknown variants"
                );
            }

            let mut discriminant: u32 = 0;
            let fields = iter
                .map(|field| -> syn::Arm {
                    match field.discriminant.as_ref() {
                        Some((_, syn::Expr::Lit(syn::ExprLit { lit: syn::Lit::Int(lit), .. }))) => {
                            discriminant = lit.base10_parse::<u32>().unwrap();
                        },
                        Some(_) => panic!("unsupported discriminant type"),

View on GitHub (pinned to 5176682b65)

Solutions

  1. Rewrite the variant with positional fields: `Unknown(u32)` or `Unknown(u32, Unknown)`.
  2. Use #[ast_node] so the Unknown variant is generated in the correct shape.

Example fix

// before
#[encoding(unknown)]
Unknown { tag: u32, value: Unknown }

// after
#[encoding(unknown)]
Unknown(u32, Unknown)
Defensive patterns

Strategy: validation

Prevention

When it happens

Trigger: derive(Encode/Decode) on an enum whose #[encoding(unknown)] variant uses named fields or has no fields at all.

Common situations: Developers 'improving' the generated Unknown variant with named fields for readability; porting serde enum styles into swc codec types.

Related errors


AI-assisted analysis of swc-project/swc@5176682b65 (2026-08-17). Data as JSON: /api/errors/1fb557c5b6f7ac08. Report an issue: GitHub.