{"record":{"id":"aa443c693aeab020","repo":"swc-project/swc","slug":"unsupported-discriminant-type-aa443c","errorCode":null,"errorMessage":"unsupported discriminant type","messagePattern":"unsupported discriminant type","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/ast_node/src/encoding/encode.rs","lineNumber":128,"sourceCode":"                        },\n                        _ => panic!(\"named enum unsupported\"),\n                    }\n                });\n\n            if matches!(enum_type, EnumType::Struct) {\n                assert!(\n                    unknown_arm.is_none(),\n                    \"struct enum does not allow unknown variants\"\n                );\n            }\n\n            let mut discriminant: u32 = 0;\n            let fields = iter.map(|field| -> syn::Arm {\n                match field.discriminant.as_ref() {\n                    Some((_, syn::Expr::Lit(syn::ExprLit { lit: syn::Lit::Int(lit), .. }))) => {\n                        discriminant = lit.base10_parse::<u32>().unwrap();\n                    },\n                    Some(_) => panic!(\"unsupported discriminant type\"),\n                    None => (),\n                };\n                discriminant += 1;\n                let idx = discriminant;\n                let name = &field.ident;\n\n                assert!(\n                    !is_unknown(&field.attrs),\n                    \"unknown member must be first: {:?}\",\n                    field.attrs.len()\n                );\n\n                match enum_type {\n                    EnumType::Unit => {\n                        assert!(\n                            is_with(&field.attrs).is_none(),\n                            \"unit member is not allowed with type\"\n                        );","sourceCodeStart":110,"sourceCodeEnd":146,"githubUrl":"https://github.com/swc-project/swc/blob/5176682b65416c6b5de6b47379ae1588ea3ecb3f/crates/ast_node/src/encoding/encode.rs#L110-L146","documentation":"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.","triggerScenarios":"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.","commonSituations":"Refactoring wire-protocol magic numbers into shared consts; enums generated from specs where discriminants arrive as named constants.","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."],"exampleFix":"// before\nconst KIND_NUM: u32 = 3;\nenum Tagged {\n    Str = 1,\n    Num = KIND_NUM,\n}\n\n// after — plain u32 literals\nenum Tagged {\n    Str = 1,\n    Num = 3,\n}","handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":["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."],"tags":["rust","proc-macro","derive","encode","enum","discriminant"],"backgroundTag":"enum-discriminant-not-literal","analyzedSha":"5176682b65416c6b5de6b47379ae1588ea3ecb3f","analyzedAt":"2026-08-17T16:16:52.067Z","contentChangedAt":"2026-08-17T16:16:52.067Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}