{"record":{"id":"cc447b4a35380277","repo":"swc-project/swc","slug":"derive-merge-does-not-support-a-unit-struct","errorCode":null,"errorMessage":"derive(Merge) does not support a unit struct","messagePattern":"derive\\(Merge\\) does not support a unit struct","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/swc_config_macro/src/merge.rs","lineNumber":51,"sourceCode":"        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()\n            .map(|(idx, f)| call_merge(obj, idx, f))\n            .map(|expr| Stmt::Expr(expr, Some(Token![;](fs.brace_token.span.join()))))\n            .collect(),\n        Fields::Unnamed(fs) => fs\n            .unnamed\n            .iter()\n            .enumerate()\n            .map(|(idx, f)| call_merge(obj, idx, f))\n            .map(|expr| Stmt::Expr(expr, Some(Token![;](fs.paren_token.span.join()))))\n            .collect(),\n        Fields::Unit => unimplemented!(\"derive(Merge) does not support a unit struct\"),\n    }\n}\n","sourceCodeStart":33,"sourceCodeEnd":54,"githubUrl":"https://github.com/swc-project/swc/blob/d7d74346665e36e692aa07e13d4ee3ee692ee35c/crates/swc_config_macro/src/merge.rs#L33-L54","documentation":"#[derive(Merge)] from swc_config_macro generates one Merge::merge call per struct field; a unit struct has no fields, so Fields::Unit reaches unimplemented!(\"derive(Merge) does not support a unit struct\") at merge.rs:51 and the proc macro panics at compile time. Unit structs are rejected because there is nothing to merge and the derive chooses to fail loudly instead of generating a no-op.","triggerScenarios":"Writing #[derive(Merge)] on a marker type like `struct Done;` in a crate using swc_config. Compilation of that crate fails with 'proc-macro derive panicked' and the message above.","commonSituations":"Adding marker/phantom types or state tags to config type hierarchies that already derive Merge; refactoring a fieldless tuple struct `struct X();`-adjacent shapes; the error confuses users because the type itself is trivial.","solutions":["Implement Merge manually with a no-op: `impl Merge for X { fn merge(&mut self, _other: Self) {} }`.","Or give the struct a field (e.g. `_priv: ()` or PhantomData) so the derive has something to merge.","Remove the derive if the type never participates in config merging.","Prefer explicit manual impls over derives for degenerate shapes."],"exampleFix":"// before\n#[derive(Merge)]\nstruct Marker;\n\n// after\nstruct Marker;\nimpl swc_config::merge::Merge for Marker {\n    fn merge(&mut self, _other: Self) {}\n}","handlingStrategy":"validation","validationCode":"// Unit structs are rejected at expansion time; validate the shape instead:\n// a type deriving Merge must be `struct Name { .. }` or `struct Name(..)` with >=1 field.\n// CI gate: flag derives on fieldless structs\n//   rg -U '#\\[derive\\([^)]*Merge[^)]*\\)\\s*(pub\\s+)?struct\\s*\\w+\\s*;' src/","typeGuard":null,"tryCatchPattern":null,"preventionTips":["For marker types, skip the derive and write a no-op manual `impl Merge`.","Or add a field (`_priv: ()` / `PhantomData<T>`) so the derive has a field to merge.","Only derive Merge on types that actually carry mergeable configuration.","Gate new derives with a quick CI pattern check for unit structs."],"tags":["swc","proc-macro","derive","merge","unit-struct","compile-time-panic"],"backgroundTag":null,"analyzedSha":"d7d74346665e36e692aa07e13d4ee3ee692ee35c","analyzedAt":"2026-08-16T12:41:13.160Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}