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
- Check `item.kind()` equals `ItemKind::Static` before calling `StaticDef::try_from`.
- If resolving by DefId/path, confirm the definition is a `static` (not a `const` or `fn`) at the call site.
- 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
- Always dispatch on `CrateItem::kind()` before narrowing; `ItemKind` has four variants (Fn, Static, Const, Ctor) and each maps to a distinct typed wrapper.
- When collecting statics, filter with `items.into_iter().filter(|i| matches!(i.kind(), ItemKind::Static))` rather than converting blindly and catching errors.
- Do not assume a `CrateItem` obtained from `Crate::fn_defs()` is a `Static`; use a static-specific enumerator if the API provides one.
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
- Item kind `{:?}` cannot be converted
- Item requires monomorphization
- {self:?}
- Const `{cnst:?}` cannot be encoded as u64
- first index in inbounds_gep
AI-assisted analysis of rust-lang/rust@22057b88b0 (2026-08-03).
Data as JSON: /data/errors/5d08e30f79a70227.json.
Report an issue: GitHub.