{"record":{"id":"e6f5a9238c186f41","repo":"swc-project/swc","slug":"union","errorCode":null,"errorMessage":"union","messagePattern":"union","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/swc_eq_ignore_macros/src/lib.rs","lineNumber":98,"sourceCode":"                let arm = self.make_arm_from_fields(parse_quote!(Self), &s.fields);\n\n                parse_quote!(match (self, other) { #arm })\n            }\n            Data::Enum(e) => {\n                //\n                let mut arms = Punctuated::<_, Token![,]>::default();\n                for v in &e.variants {\n                    let vi = &v.ident;\n                    let arm = self.make_arm_from_fields(parse_quote!(Self::#vi), &v.fields);\n\n                    arms.push(arm);\n                }\n\n                arms.push(parse_quote!(_ => false));\n\n                parse_quote!(match (self, other) { #arms })\n            }\n            Data::Union(_) => unimplemented!(\"union\"),\n        }\n    }\n\n    fn make_arm_from_fields(&self, pat_path: Path, fields: &Fields) -> Arm {\n        let mut l_pat_fields = Punctuated::<_, Token![,]>::default();\n        let mut r_pat_fields = Punctuated::<_, Token![,]>::default();\n        let mut exprs = Vec::new();\n\n        for (i, field) in fields\n            .iter()\n            .enumerate()\n            .filter(|(_, f)| !(self.ignore_field)(f))\n        {\n            let method_name =\n                if field.attrs.iter().any(|attr| {\n                    attr.path().is_ident(\"not_spanned\") || attr.path().is_ident(\"use_eq\")\n                }) {\n                    Ident::new(\"eq\", Span::call_site())","sourceCodeStart":80,"sourceCodeEnd":116,"githubUrl":"https://github.com/swc-project/swc/blob/d7d74346665e36e692aa07e13d4ee3ee692ee35c/crates/swc_eq_ignore_macros/src/lib.rs#L80-L116","documentation":"`#[derive(EqIgnoreSpan)]` generates span-insensitive equality for structs and enums by emitting one match arm per variant. `Data::Union(_) => unimplemented!(\"union\")` — deriving it on a Rust union panics at compile time because there is no union strategy yet.","triggerScenarios":"Write `#[derive(EqIgnoreSpan)] union MyUnion { a: u32, b: f32 }` in a crate that depends on swc_eq_ignore_macros.","commonSituations":"AST-like crates modeling bitsets or byte layouts as unions; derive lists applied broadly via macros or templates; internal swc work adding unions to AST types.","solutions":["Wrap the union in a struct, derive on the struct, and hand-write an EqIgnoreSpan impl comparing the raw bytes/fields","Convert the union to a struct if the union layout is not required","Contribute a `Data::Union` arm upstream"],"exampleFix":"// before\n#[derive(EqIgnoreSpan)]\nunion U { a: u32, b: f32 }\n\n// after\n#[derive(EqIgnoreSpan)]\nstruct U { bits: u32 } // compare via bits; or impl manually","handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never place #[derive(EqIgnoreSpan)] on a union; wrap or convert instead","When applying derives via shared macro lists, exclude unions explicitly"],"tags":["macro","derive","rust","compile-time","union"],"backgroundTag":null,"analyzedSha":"d7d74346665e36e692aa07e13d4ee3ee692ee35c","analyzedAt":"2026-08-16T12:41:13.160Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}