linebender/druid · error

Unwrap named called on unnamed FieldIdent

Error message

Unwrap named called on unnamed FieldIdent

What it means

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.

Solutions

  1. Use a named struct (fields with names) instead of a tuple struct for types deriving druid traits that need named fields
  2. If a tuple struct is required, wrap the fields in named-field structs or use `#[druid/lens]` overrides pointing at supported structures
  3. Verify the derive targets the correct struct, not one of its tuple-variant components

Example fix

// before
#[derive(Lens)]
struct Point(f64, f64);

// after
#[derive(Lens)]
struct Point { x: f64, y: f64 }
Defensive patterns

Strategy: type-guard

Validate before calling

match field_ident { FieldIdent::Named(_) => {}, FieldIdent::Unnamed(i) => panic!("derive requires named fields; got index {}", i) }

Type guard

fn is_named(fi: &FieldIdent) -> bool { matches!(fi, FieldIdent::Named(_)) }

Prevention

When it happens

Trigger: 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`.

Common situations: 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.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of linebender/druid@0f8b1195e4 (2026-09-10). Data as JSON: /api/errors/ca3d65fa0e8ea222. Report an issue: GitHub.

Appendix: source

Thrown at druid-derive/src/attr.rs:47

pub enum FieldKind {
    Named,
    // this also covers Unit; we determine 'unit-ness' based on the number
    // of fields.
    Unnamed,
}

#[derive(Debug)]
pub enum FieldIdent {
    Named(String),
    Unnamed(usize),
}

impl FieldIdent {
    pub fn unwrap_named(&self) -> syn::Ident {
        if let FieldIdent::Named(s) = self {
            syn::Ident::new(s, Span::call_site())
        } else {
            panic!("Unwrap named called on unnamed FieldIdent");
        }
    }
}

#[derive(Debug)]
pub struct Field<Attrs> {
    pub ident: FieldIdent,
    pub ty: syn::Type,

    pub attrs: Attrs,
}

#[derive(Debug, PartialEq, Eq)]
pub enum DataAttr {
    Empty,
    Ignore,
    SameFn(ExprPath),
    Eq,

View on GitHub (pinned to 0f8b1195e4)