rust-lang/rust · critical
Unexpected {} code: {:?}
Error message
Unexpected {} code: {:?} What it means
Generated by the `fixed_size_enum!` macro in table.rs:89 inside `Option<T>::from_bytes`. rmeta stores fixed-size enums (e.g. Option<DefKind>, Option<CoroutineKind>, Option<MacroKind>) as single bytes where 0 = None and n = Some(variant n-1). A decoded byte that doesn't map to any known variant triggers this panic, proving the bytes are inconsistent with the decoder's enum definition.
Source
Thrown at compiler/rustc_metadata/src/rmeta/table.rs:89
fn write_to_bytes(self, b: &mut [u8; 8]) {
*b = self.to_le_bytes();
}
}
macro_rules! fixed_size_enum {
($ty:ty { $(($($pat:tt)*))* } $( unreachable { $(($($upat:tt)*))+ } )?) => {
impl FixedSizeEncoding for Option<$ty> {
type ByteArray = [u8;1];
#[inline]
fn from_bytes(b: &[u8;1]) -> Self {
use $ty::*;
if b[0] == 0 {
return None;
}
match b[0] - 1 {
$(${index()} => Some($($pat)*),)*
_ => panic!("Unexpected {} code: {:?}", stringify!($ty), b[0]),
}
}
#[inline]
fn write_to_bytes(self, b: &mut [u8;1]) {
use $ty::*;
b[0] = match self {
None => unreachable!(),
$(Some($($pat)*) => 1 + ${index()},)*
$(Some($($($upat)*)|+) => unreachable!(),)?
}
}
}
}
}
macro_rules! defaulted_enum {
($ty:ty { $(($($pat:tt)*))* } $( unreachable { $(($($upat:tt)*))+ } )?) => {View on GitHub (pinned to 22057b88b0)
Solutions
- Run `cargo clean` and rebuild the whole dependency tree with one consistent toolchain (`rustup show`, pin via `rust-toolchain.toml`).
- Delete stale incremental artifacts (`rm -rf target/debug/incremental` or the relevant profile dir) and rebuild.
- If it reproduces on a clean build with a single toolchain, capture a minimal repro and file a rustc issue — likely an encoder/decoder table out of sync.
Defensive patterns
Strategy: validation
Validate before calling
// Decode against an expected/known code range before handing the
// table to the consumer that would otherwise `unwrap`/`bug!`.
fn validate_table_code(kind: TableKind, code: u32) -> Result<(), String> {
let max = kind.known_max_code();
if code as usize <= max {
Ok(())
} else {
Err(format!("unexpected {} code: {:?} (max known={})", kind, code, max))
}
} Type guard
fn is_known_table_code(kind: TableKind, code: u32) -> bool {
kind.known_codes().contains(&code)
} Try / catch
// Rust panics are not exceptions; isolate untrusted metadata decoding
// behind catch_unwind at a process/worker boundary.
let result = std::panic::catch_unwind(|| decode_rmeta_table(&bytes));
match result {
Ok(table) => use_table(table),
Err(payload) => report_corrupt_metadata(payload),
} Prevention
- Do not consume .rmeta/.rlib files from a different/unstable rustc version; rmeta table layout is unstable across commits.
- Pin toolchain versions in CI (rust-toolchain.toml) so generated metadata and consumer are always the same build.
- Validate checksums / hashes of cached metadata before reuse; partial writes commonly surface as unexpected codes.
- If you write a custom rmeta consumer, snapshot-test against real compiler output and fail loudly on schema drift.
When it happens
Trigger: Decoding an .rmeta/.rlib whose encoded enum discriminant has no match in the current compiler's variant list — produced by a rustc that added/removed/reordered enum variants, by a corrupted metadata blob, or by an internal encoder bug that wrote an out-of-range discriminant.
Common situations: Mixing artifacts compiled with different rustc versions (notably across nightlies that extend DefKind/CoroutineKind/MacroKind), pointing Cargo at a toolchain different from the one that built a dependency, or a stale incremental cache carrying incompatible metadata.
Related errors
- cannot export more than U32_MAX files
- Invalid DepKind {u}
- unexpected self ty `{:?}` when normalizing `<T as Pointee>::
- unsupported integer: {self:?}
- unsupported float: {self:?}
AI-assisted analysis of rust-lang/rust@22057b88b0 (2026-08-03).
Data as JSON: /data/errors/3179b9c62eab6e97.json.
Report an issue: GitHub.