{"record":{"id":"db4d59354e59197f","repo":"swc-project/swc","slug":"derive-merge-does-not-support-an-enum","errorCode":null,"errorMessage":"derive(Merge) does not support an enum","messagePattern":"derive\\(Merge\\) does not support an enum","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/swc_config_macro/src/merge.rs","lineNumber":22,"sourceCode":"use syn::{parse_quote, DeriveInput, Expr, Field, Fields, Stmt, Token};\n\npub fn expand(input: DeriveInput) -> TokenStream {\n    match &input.data {\n        syn::Data::Struct(s) => {\n            let body = call_merge_for_fields(&quote!(self), &s.fields);\n            let body = join_stmts(&body);\n\n            let ident = &input.ident;\n            parse_quote!(\n                #[automatically_derived]\n                impl swc_config::merge::Merge for #ident {\n                    fn merge(&mut self, _other: Self) {\n                        #body\n                    }\n                }\n            )\n        }\n        syn::Data::Enum(_) => unimplemented!(\"derive(Merge) does not support an enum\"),\n        syn::Data::Union(_) => unimplemented!(\"derive(Merge) does not support a union\"),\n    }\n}\n\nfn call_merge_for_fields(obj: &dyn ToTokens, fields: &Fields) -> Vec<Stmt> {\n    fn call_merge(obj: &dyn ToTokens, idx: usize, f: &Field) -> Expr {\n        let r = quote!(_other);\n\n        let l = access_field(obj, idx, f);\n        let r = access_field(&r, idx, f);\n        parse_quote!(swc_config::merge::Merge::merge(&mut #l, #r))\n    }\n\n    match fields {\n        Fields::Named(fs) => fs\n            .named\n            .iter()\n            .enumerate()","sourceCodeStart":4,"sourceCodeEnd":40,"githubUrl":"https://github.com/swc-project/swc/blob/d7d74346665e36e692aa07e13d4ee3ee692ee35c/crates/swc_config_macro/src/merge.rs#L4-L40","documentation":"The #[derive(Merge)] macro from swc_config_macro generates merge code by matching on syn::Data; only structs with named or unnamed fields are supported. Deriving it on an enum reaches unimplemented!(\"derive(Merge) does not support an enum\") at merge.rs:22, which panics during macro expansion — i.e. at compile time of the crate using the derive.","triggerScenarios":"Annotating an enum with #[derive(Merge)] in a crate that depends on swc_config / swc_config_macro, e.g. trying to make a config enum overridable. rustc aborts with the macro's panic message during compilation.","commonSituations":"Defining SWC config option types (transforms, plugin options) as enums for ergonomics and assuming derive(Merge) behaves like serde derives; upgrading config types from structs to tagged enums; error appears as 'proc-macro derive panicked' in build output.","solutions":["Convert the enum into a struct whose fields are each merge-able (structs with named/unnamed fields are supported).","Implement swc_config::merge::Merge manually for the enum with your chosen precedence (e.g. other wins when non-default).","Wrap the enum in a struct and derive Merge on the wrapper, implementing Merge by hand for the inner enum.","If Unit-like variants are involved, also see the unit-struct restriction."],"exampleFix":"// before\n#[derive(Merge)]\nenum Mode { Fast, Slow }\n\n// after\nenum Mode { Fast, Slow }\nimpl swc_config::merge::Merge for Mode {\n    fn merge(&mut self, other: Self) {\n        // define precedence explicitly\n        if matches!(self, Mode::Fast) { *self = other; }\n    }\n}","handlingStrategy":"validation","validationCode":"// The panic is at macro-expansion time; the only 'validation' is reviewing\n// the derive input shape before compiling:\n// - #[derive(Merge)] requires a struct (named or unnamed fields, at least one field).\n// - Enums and unit structs are rejected.\n// Fail fast in review/CI with a grep:\n//   rg -U '#\\[derive\\([^)]*Merge[^)]*\\)\\s*(pub\\s+)?enum' src/","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Derive Merge only on structs with fields; for enums write a manual Merge impl with explicit precedence.","If you need enum config options, model them as newtype structs over an inner enum and implement Merge for the inner type by hand.","Add a CI grep/regex gate for `#[derive(...Merge...)]` immediately followed by `enum` or a unit struct body.","Read the derive's docs (swc_config::merge) before applying it to new type shapes."],"tags":["swc","proc-macro","derive","merge","config","compile-time-panic"],"backgroundTag":null,"analyzedSha":"d7d74346665e36e692aa07e13d4ee3ee692ee35c","analyzedAt":"2026-08-16T12:41:13.160Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}