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

Expected a static item, but found: {value:?}

Error message

Expected a static item, but found: {value:?}

What it means

Thrown by `TryFrom<CrateItem> for StaticDef` in compiler/rustc_public/src/mir/mono.rs:284 when the crate item is not a static variable. `StaticDef` is only meaningful for `ItemKind::Static`, so passing a function, const, trait, or module item fails. rustc_public enforces the kind match because a static has a fixed address and an initializer that other item kinds do not have.

Source

Thrown at compiler/rustc_public/src/mir/mono.rs:284

    fn def_id(&self) -> DefId {
        with(|context| context.instance_def_id(*self))
    }
}

crate_def! {
    /// Holds information about a static variable definition.
    #[derive(Serialize)]
    pub StaticDef;
}

impl TryFrom<CrateItem> for StaticDef {
    type Error = crate::Error;

    fn try_from(value: CrateItem) -> Result<Self, Self::Error> {
        if matches!(value.kind(), ItemKind::Static) {
            Ok(StaticDef(value.0))
        } else {
            Err(bridge::Error::new(format!("Expected a static item, but found: {value:?}")))
        }
    }
}

impl TryFrom<Instance> for StaticDef {
    type Error = crate::Error;

    fn try_from(value: Instance) -> Result<Self, Self::Error> {
        StaticDef::try_from(CrateItem::try_from(value)?)
    }
}

impl From<StaticDef> for Instance {
    fn from(value: StaticDef) -> Self {
        // A static definition should always be convertible to an instance.
        with(|cx| cx.mono_instance(value.def_id()))
    }
}

View on GitHub (pinned to 22057b88b0)

Solutions

  1. Check `item.kind()` equals `ItemKind::Static` before calling `StaticDef::try_from`.
  2. If resolving by DefId/path, confirm the definition is a `static` (not a `const` or `fn`) at the call site.
  3. On the instance path, remember the conversion goes `Instance -> CrateItem -> StaticDef`; ensure the originating instance is a static before attempting it.

Example fix

// before
let def = StaticDef::try_from(item)?;
// after
let def = match item.kind() {
    ItemKind::Static => StaticDef::try_from(item)?,
    _ => continue,
};
Defensive patterns

Strategy: type-guard

Validate before calling

// Before StaticDef::try_from(item):
if !matches!(item.kind(), ItemKind::Static) {
    return Err(format!("item {:?} is {:?}, not a static", item, item.kind()));
}
let static_def = StaticDef::try_from(item)?;

Type guard

// True only for `static` items.
fn is_static_item(item: &CrateItem) -> bool {
    matches!(item.kind(), ItemKind::Static)
}

Try / catch

match StaticDef::try_from(item) {
    Ok(s) => s,
    Err(e) if e.to_string().contains("Expected a static item") => {
        // Item is Fn/Const/Ctor; route it to the right handler by kind.
        return route_by_kind(item);
    }
    Err(e) => return Err(e.into()),
}

Prevention

When it happens

Trigger: Calling `StaticDef::try_from(crate_item)` or `StaticDef::try_from(instance)` (via the `Instance -> CrateItem -> StaticDef` chain) on an item whose `kind()` is not `ItemKind::Static`. Blindly converting every item in a crate to a `StaticDef`.

Common situations: Analyzers that scan for statics and forget to filter by item kind. Using a DefId-by-path lookup that resolves to a `const` rather than a `static` (a common confusion since both look similar). Refactors that changed a `static` to a `const`.

Related errors


AI-assisted analysis of rust-lang/rust@22057b88b0 (2026-08-03). Data as JSON: /data/errors/5d08e30f79a70227.json. Report an issue: GitHub.