{"record":{"id":"ca3d65fa0e8ea222","repo":"linebender/druid","slug":"unwrap-named-called-on-unnamed-fieldident","errorCode":null,"errorMessage":"Unwrap named called on unnamed FieldIdent","messagePattern":"Unwrap named called on unnamed FieldIdent","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"druid-derive/src/attr.rs","lineNumber":47,"sourceCode":"pub enum FieldKind {\n    Named,\n    // this also covers Unit; we determine 'unit-ness' based on the number\n    // of fields.\n    Unnamed,\n}\n\n#[derive(Debug)]\npub enum FieldIdent {\n    Named(String),\n    Unnamed(usize),\n}\n\nimpl FieldIdent {\n    pub fn unwrap_named(&self) -> syn::Ident {\n        if let FieldIdent::Named(s) = self {\n            syn::Ident::new(s, Span::call_site())\n        } else {\n            panic!(\"Unwrap named called on unnamed FieldIdent\");\n        }\n    }\n}\n\n#[derive(Debug)]\npub struct Field<Attrs> {\n    pub ident: FieldIdent,\n    pub ty: syn::Type,\n\n    pub attrs: Attrs,\n}\n\n#[derive(Debug, PartialEq, Eq)]\npub enum DataAttr {\n    Empty,\n    Ignore,\n    SameFn(ExprPath),\n    Eq,","sourceCodeStart":29,"sourceCodeEnd":65,"githubUrl":"https://github.com/linebender/druid/blob/0f8b1195e4e073f9597f2865299c3d18f8e4005f/druid-derive/src/attr.rs#L29-L65","documentation":"druid-derive's `FieldIdent::unwrap_named` panics when called on a `FieldIdent::Unnamed` (a tuple-struct field index) instead of a named field. The derive macro uses this to extract field identifier strings, and it can only operate on named fields. The panic is an internal invariant check in the derive implementation.","triggerScenarios":"The derive macro code path that requires a named field identifier is reached while processing an unnamed (tuple) field, e.g. a derive on a tuple struct or a generated `FieldIdent::Unnamed(index)` is passed to `unwrap_named`.","commonSituations":"Applying druid derives that access fields by name (e.g. `#[derive(Data, Lens)]`) to a tuple struct like `struct Foo(u32, String)`, where the macro internally unwraps field identifiers.","solutions":["Use a named struct (fields with names) instead of a tuple struct for types deriving druid traits that need named fields","If a tuple struct is required, wrap the fields in named-field structs or use `#[druid/lens]` overrides pointing at supported structures","Verify the derive targets the correct struct, not one of its tuple-variant components"],"exampleFix":"// before\n#[derive(Lens)]\nstruct Point(f64, f64);\n\n// after\n#[derive(Lens)]\nstruct Point { x: f64, y: f64 }","handlingStrategy":"type-guard","validationCode":"match field_ident { FieldIdent::Named(_) => {}, FieldIdent::Unnamed(i) => panic!(\"derive requires named fields; got index {}\", i) }","typeGuard":"fn is_named(fi: &FieldIdent) -> bool { matches!(fi, FieldIdent::Named(_)) }","tryCatchPattern":null,"preventionTips":["Only apply druid derives that need named fields to structs with named fields","Review derive targets when refactoring structs to tuple form"],"tags":["derive-macro","rust","panic","named-fields"],"backgroundTag":"invalid-argument-value","analyzedSha":"0f8b1195e4e073f9597f2865299c3d18f8e4005f","analyzedAt":"2026-09-10T14:27:34.582Z","contentChangedAt":"2026-09-10T14:27:34.582Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}