rust-lang/rust · critical
variant_with_id: unknown variant
Error message
variant_with_id: unknown variant
What it means
This `expect` in adt.rs:598 (`variant_with_id`) fires when `AdtDef::variants()` does not contain a `VariantDef` whose `def_id` equals the queried `vid`. The ADT's variant list is built once during HIR lowering/TyCtxt construction; a lookup miss indicates a stale or mismatched DefId was handed to the ADT — an internal consistency bug, normally not reachable from valid user code. Sibling lookups (`variant_with_ctor_id`, `variant_index_with_id`) share the same invariant.
Source
Thrown at compiler/rustc_middle/src/ty/adt.rs:598
// This would disallow the following kind of enum from being casted into integer.
// ```
// enum Enum {
// Foo() = 1,
// Bar{} = 2,
// Baz = 3,
// }
// ```
if self.variants().iter().any(|v| {
matches!(v.discr, VariantDiscr::Explicit(_)) && v.ctor_kind() != Some(CtorKind::Const)
}) {
return false;
}
self.variants().iter().all(|v| v.fields.is_empty())
}
/// Return a `VariantDef` given a variant id.
pub fn variant_with_id(self, vid: DefId) -> &'tcx VariantDef {
self.variants().iter().find(|v| v.def_id == vid).expect("variant_with_id: unknown variant")
}
/// Return a `VariantDef` given a constructor id.
pub fn variant_with_ctor_id(self, cid: DefId) -> &'tcx VariantDef {
self.variants()
.iter()
.find(|v| v.ctor_def_id() == Some(cid))
.expect("variant_with_ctor_id: unknown variant")
}
/// Return the index of `VariantDef` given a variant id.
#[inline]
pub fn variant_index_with_id(self, vid: DefId) -> VariantIdx {
self.variants()
.iter_enumerated()
.find(|(_, v)| v.def_id == vid)
.expect("variant_index_with_id: unknown variant")
.0View on GitHub (pinned to 22057b88b0)
Solutions
- Run `cargo clean` and rebuild to rule out incremental-cache desync.
- Pin or upgrade the toolchain to a known-good nightly (the ICE is usually fixed quickly once reported).
- Reduce the failing crate and file an ICE report at https://github.com/rust-lang/rust with the backtrace and `RUST_BACKTRACE=full` output.
- If a proc-macro is involved, check that it emits fresh spans/DefIds rather than caching them across compilations.
Defensive patterns
Strategy: retry
Validate before calling
// variant_with_id failures almost always mean stale/corrupt rmeta for an enum variant.
// Validate the build artifacts are fresh before trusting any ADT variant index.
fn build_artifacts_fresh(meta_stamp: std::time::SystemTime, src_stamp: std::time::SystemTime) -> bool {
meta_stamp > src_stamp // metadata newer than source -> safe to trust variant ids
} Type guard
// Confirm a variant still exists in the *current* metadata before indexing by id.
fn variant_exists<E: EnumProbe>(id: u32) -> bool {
E::variant_count() > id
} Prevention
- On first sighting, run `cargo clean && cargo build` — unknown-variant ICEs are dominated by stale incremental/rmeta caches, not real bugs.
- Avoid hand-editing generated enum code without bumping the crate version; downstream variant ids go stale silently.
- Disable `-Zincremental` in CI; incremental caches are the usual source of variant-id drift.
- If it reproduces after a clean build, isolate the offending enum and report with `--pretty=expanded`.
When it happens
Trigger: Called when the compiler resolves `Res::Def(DefKind::Variant, vid)` via `variant_of_res` (adt.rs:628) or directly via `tcx.adt_def(..).variant_with_id(did)`, but `did` is not a variant of that ADT — e.g. a DefId from a different enum passed in due to an incremental-compilation cache desync or a HIR query ordering bug.
Common situations: Incremental compilation (`-C incremental`) corruption after a compiler upgrade; proc-macro or macro_rules that synthesizes enum variant references; rename/refactor of an enum variant leaving a stale DefId in a cached query; enum variants generated by a derive macro whose input changed.
Related errors
- local id should be u32, found {local_id:?}
- Failed to get parent for {child:?}
- expected to be able to unify goal projection with dyn's proj
- Sized/MetaSized is never const
- AsyncFnKindHelper is not const
AI-assisted analysis of rust-lang/rust@22057b88b0 (2026-08-03).
Data as JSON: /data/errors/d750855014d403a4.json.
Report an issue: GitHub.