rust-lang/rust · critical
Unexpected type {:?}
Error message
Unexpected type {:?} What it means
Panics in extract_value when the aggregate value is neither an array, a vector, nor a struct. The message prints the offending value_type, indicating rustc asked the backend to extract a field from a value whose GCC type the backend does not recognise as an aggregate kind.
Source
Thrown at compiler/rustc_codegen_gcc/src/builder.rs:1544
fn extract_value(&mut self, aggregate_value: RValue<'gcc>, idx: u64) -> RValue<'gcc> {
// FIXME(antoyo): it would be better if the API only called this on struct, not on arrays.
assert_eq!(idx as usize as u64, idx);
let value_type = aggregate_value.get_type();
if value_type.dyncast_array().is_some() {
let index = self
.context
.new_rvalue_from_long(self.u64_type, i64::try_from(idx).expect("i64::try_from"));
let element = self.context.new_array_access(self.location, aggregate_value, index);
element.get_address(self.location)
} else if value_type.dyncast_vector().is_some() {
panic!();
} else if let Some(struct_type) = value_type.is_struct() {
aggregate_value
.access_field(self.location, struct_type.get_field(idx as i32))
.to_rvalue()
} else {
panic!("Unexpected type {:?}", value_type);
}
}
fn insert_value(
&mut self,
aggregate_value: RValue<'gcc>,
value: RValue<'gcc>,
idx: u64,
) -> RValue<'gcc> {
// FIXME(antoyo): it would be better if the API only called this on struct, not on arrays.
assert_eq!(idx as usize as u64, idx);
let value_type = aggregate_value.get_type();
let new_val = self.current_func().new_local(None, value_type, "aggregate_value");
self.block.add_assignment(None, new_val, aggregate_value);
let lvalue = if value_type.dyncast_array().is_some() {
let index = selfView on GitHub (pinned to 22057b88b0)
Solutions
- Reproduce with the failing crate, capture the printed value_type, and report it upstream so the missing type kind can be handled.
- Update rustc_codegen_gcc to a commit that recognises the additional aggregate type and routes it correctly.
- As a temporary local workaround, lower the offending construct differently in the source crate (e.g. avoid the type/representation that triggers extract_value on it).
Example fix
// before
} else {
panic!("Unexpected type {:?}", value_type);
}
// after
} else {
bug!("extract_value on unsupported aggregate type {:?}", value_type);
} Defensive patterns
Strategy: type-guard
Type guard
use gccjit::Type;
#[derive(Debug)]
enum SupportedAggregate { Array, Struct }
fn classify_for_extract_value(ty: Type<'_>) -> Option<SupportedAggregate> {
if ty.dyncast_array().is_some() {
Some(SupportedAggregate::Array)
} else if ty.is_struct().is_some() {
Some(SupportedAggregate::Struct)
} else {
None // vector, union, opaque, fn, etc. -> would hit "Unexpected type"
}
}
// guard before extract_value:
match classify_for_extract_value(aggregate_value.get_type()) {
Some(kind) => extract_value(aggregate_value, idx),
None => return Err(format!("extract_value: unsupported aggregate kind")),
} Prevention
- extract_value in cg_gcc only handles arrays and structs — reject unions, vectors, opaque/fn types, or any non-aggregate before codegen.
- Avoid unions and repr(packed) aggregates that lower to extractvalue; lower them to explicit byte loads instead.
- Run the crate's codegen tests under cg_gcc in CI to surface unsupported aggregate shapes before they reach users.
- When wrapping the builder, classify the type up front and emit a clear, localized error rather than letting the backend hit the generic panic.
When it happens
Trigger: extract_value is called on a RValue whose value_type returns None for dyncast_array, dyncast_vector, and is_struct. This occurs when a non-aggregate (e.g. a scalar, pointer, or opaque libgccjit type) reaches the aggregate-extraction code path.
Common situations: Arises after rustc internals change how certain types are represented, or when libgccjit returns an unexpected type kind for a fat-pointer/unsized value. Crates exercising DSTs, trait-object fat pointers, or exotic representations are common triggers.
Related errors
- i64::try_from
- vector type
- mask should be of struct type
- Size::bits: {bytes} bytes in bits doesn't fit in u64
- Size::add: {} + {} doesn't fit in u64
AI-assisted analysis of rust-lang/rust@22057b88b0 (2026-08-03).
Data as JSON: /data/errors/a09e7222fff0d935.json.
Report an issue: GitHub.