rust-lang/rust · error · syn::Error

key `{key}` specified twice

Error message

key `{key}` specified twice

What it means

Each function name (or the `_` default) may appear in only one fn_extra arm. extract_fn_extra_field() inserts keys into a BTreeMap and rejects a second insertion of the same key (parse.rs:202-208). Overlap can arise from `|` alternatives, duplicate arms, or from ALL_* group matchers expanding to functions also named explicitly.

Source

Thrown at library/compiler-builtins/crates/libm-macros/src/parse.rs:205

            comma: _,
        } = arm;

        expect_empty_attrs(&attrs)?;

        let keys = match pat {
            syn::Pat::Wild(w) => vec![Ident::new("_", w.span())],
            _ => Parser::parse2(parse_ident_pat, pat.into_token_stream())?,
        };

        if let Some(guard) = guard {
            let e = syn::Error::new(guard.0.span(), "no guards allowed in this position");
            return Err(e);
        }

        for key in keys {
            let inserted = res.insert(key.clone(), *body.clone());
            if inserted.is_some() {
                let e = syn::Error::new(key.span(), format!("key `{key}` specified twice"));
                return Err(e);
            }
        }
    }

    Ok(res)
}

fn expect_empty_attrs(attrs: &[Attribute]) -> syn::Result<()> {
    if attrs.is_empty() {
        return Ok(());
    }

    let e = syn::Error::new(
        attrs.first().unwrap().span(),
        "no attributes allowed in this position",
    );
    Err(e)

View on GitHub (pinned to 7088e4b63a)

Solutions

  1. Remove the duplicate key so each function name appears in exactly one arm.
  2. If using ALL_* group matchers, ensure no explicit arm repeats a function contained in that group.

Example fix

// before
fn_extra: match MACRO_FN_NAME {
    ALL_F64 => |x| x,
    sqrt => |x| x.sqrt(),
    _ => |x| x,
},
// after
fn_extra: match MACRO_FN_NAME {
    sqrt => |x| x.sqrt(),
    ALL_F64 => |x| x,
    _ => |x| x,
},  // note: remove sqrt from the ALL_F64 intent or drop the explicit arm
Defensive patterns

Strategy: validation

Prevention

When it happens

Trigger: `fn_extra: match MACRO_FN_NAME { sin | sin => ... }`, two arms both listing `sin`, or using `ALL_F64` alongside an explicit arm for a function that ALL_F64 expands to (validate() expands group matchers, lib.rs:143-172).

Common situations: Adding an explicit arm for a function already covered by an ALL_F64/ALL_F32 group; duplicate alternatives via `|`.

Related errors


AI-assisted analysis of rust-lang/rust@7088e4b63a (2026-08-10). Data as JSON: /api/errors/2a0d8f0ad5edc479. Report an issue: GitHub.