swc-project/swc · error
unsupported discriminant type
Error message
unsupported discriminant type
What it means
The Encode derive assigns each variant a CBOR index from a running u32 counter; an explicit discriminant is honored only when it is an integer literal (syn::Lit::Int) that parses as u32 — no const evaluation happens. `Variant = SOME_CONST` or any non-literal expression hits `Some(_) => panic!("unsupported discriminant type")`. Values that overflow u32 also fail in the subsequent parse unwrap.
Source
Thrown at crates/ast_node/src/encoding/encode.rs:128
},
_ => 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"),
None => (),
};
discriminant += 1;
let idx = discriminant;
let name = &field.ident;
assert!(
!is_unknown(&field.attrs),
"unknown member must be first: {:?}",
field.attrs.len()
);
match enum_type {
EnumType::Unit => {
assert!(
is_with(&field.attrs).is_none(),
"unit member is not allowed with type"
);View on GitHub (pinned to 5176682b65)
Solutions
- Inline the value as an integer literal: `Num = 3`.
- Or omit explicit discriminants and let the macro assign sequential indices.
- Guard against drift with a test asserting the encoded tag value.
Example fix
// before
const KIND_NUM: u32 = 3;
enum Tagged {
Str = 1,
Num = KIND_NUM,
}
// after — plain u32 literals
enum Tagged {
Str = 1,
Num = 3,
} Defensive patterns
Strategy: validation
Prevention
- Write enum discriminants as plain u32 integer literals in the enum definition.
- Share wire values via tests that assert the encoded tag, not via consts spliced into the enum.
- Avoid negative, float, or const-path discriminants on codec-derived enums.
When it happens
Trigger: derive(Encode) on an enum where a variant discriminant is a path/const, negative number, or other non-literal expression rather than a plain u32 integer literal.
Common situations: Refactoring wire-protocol magic numbers into shared consts; enums generated from specs where discriminants arrive as named constants.
Related errors
- unsupported discriminant type
- more than 1 unnamed member field are not allowed
- enum member types must be consistent: {:?}
- unknown member must be a tag and a value
- named enum unsupported
AI-assisted analysis of swc-project/swc@5176682b65 (2026-08-17).
Data as JSON: /api/errors/aa443c693aeab020.
Report an issue: GitHub.