rust-lang/rust · error
element type
Error message
element type
What it means
This panic is raised in `Builder::gcc_not` when a non-native integer type (i.e. a 128-bit integer emulated as a 2-element array of i64/u64) cannot be decomposed because `typ.dyncast_array()` returns `None`. The codegen backend assumes any type that is not a native int/bool and reaches this branch must be an array-of-two-native-ints representation of i128/u128. If that invariant is violated — e.g. a pointer, struct, or vector value is fed in — the expect fails.
Source
Thrown at compiler/rustc_codegen_gcc/src/int.rs:39
impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
pub fn gcc_urem(&self, a: RValue<'gcc>, b: RValue<'gcc>) -> RValue<'gcc> {
// 128-bit unsigned %: __umodti3
self.multiplicative_operation(BinaryOp::Modulo, "mod", false, a, b)
}
pub fn gcc_srem(&self, a: RValue<'gcc>, b: RValue<'gcc>) -> RValue<'gcc> {
// 128-bit signed %: __modti3
self.multiplicative_operation(BinaryOp::Modulo, "mod", true, a, b)
}
pub fn gcc_not(&self, a: RValue<'gcc>) -> RValue<'gcc> {
let typ = a.get_type();
if self.is_native_int_type_or_bool(typ) {
let operation =
if typ.is_bool() { UnaryOp::LogicalNegate } else { UnaryOp::BitwiseNegate };
self.cx.context.new_unary_op(self.location, operation, typ, a)
} else {
let element_type = typ.dyncast_array().expect("element type");
self.concat_low_high_rvalues(
typ,
self.cx.context.new_unary_op(
self.location,
UnaryOp::BitwiseNegate,
element_type,
self.low(a),
),
self.cx.context.new_unary_op(
self.location,
UnaryOp::BitwiseNegate,
element_type,
self.high(a),
),
)
}
}
View on GitHub (pinned to 22057b88b0)
Solutions
- Inspect the offending `RValue`'s type with a debugger or `eprintln!` to confirm what `is_native_int_type_or_bool` returned false for; it is almost always a misclassified native int, bool, or pointer.
- Verify the target triple: on 32-bit targets i128/u128 are non-native and must be arrays — confirm `concat_low_high`/`dyncast_array` agree on the array shape.
- Check recent changes to `TypeReflection` / `is_native_int_type_or_bool` in crate::common; a missing arm can cause a real native type to be treated as non-native.
- If a genuinely new type reaches `gcc_not`, extend the type-classification helpers rather than widening this `expect`.
Example fix
// before
let element_type = typ.dyncast_array().expect("element type");
// after (fail with an actionable diagnostic naming the type)
let element_type = typ.dyncast_array().unwrap_or_else(|| {
panic!("gcc_not: expected non-native int array, got {:?}", typ);
}); Defensive patterns
Strategy: type-guard
Validate before calling
// Before calling gcc_not(a), confirm `a`'s type is either a native int/bool
// or a gccjit array (the 128-bit emulation shape). Otherwise expect() panics.
let typ = a.get_type();
if !(builder.is_native_int_type_or_bool(typ) || typ.dyncast_array().is_some()) {
return Err(format!("gcc_not: type {:?} is neither native int nor a dyncast array", typ));
}
builder.gcc_not(a) Type guard
/// True when the type is safe to feed to bitwise-not (gcc_not).
fn is_notable_int_type<'gcc>(&self, typ: gccjit::Type<'gcc>) -> bool {
self.is_native_int_type_or_bool(typ) || typ.dyncast_array().is_some()
}
// usage
if builder.is_notable_int_type(a.get_type()) {
builder.gcc_not(a)
} else {
// fall back: materialize as a native-width value first
} Prevention
- Never feed a pointer, float, aggregate, or zero-sized type into gcc_not; it only handles native ints, bools, and the 2-element array used to emulate 128-bit integers.
- On 32-bit targets, u128/i128 are emulated as a [u64; 2]-style gccjit array; confirm the value was constructed via concat_low_high* before bitwise ops, or compile that code with the LLVM backend.
- If you build RValues from C FFI, assert the gccjit TypeKind is integral (TypeKind::Int/UInt/Bool) before invoking unary not.
When it happens
Trigger: Calling `Builder::gcc_not(a)` where `a.get_type()` returns a type that is neither a native integer/bool (`is_native_int_type_or_bool` is false) nor a libgccjit array type (`dyncast_array()` yields `None`). Reached when rustc lowers a `!` (bitwise not) MIR statement on a value whose GCC type was misclassified as non-native.
Common situations: Appears as an ICE when cross-compiling to a 32-bit target that lacks native 128-bit integers, after a change in how a custom type/ABI is represented, or when a type-reflection bug in `TypeReflection::is_native_int_type_or_bool` wrongly routes a native value down the non-native path. Often a symptom rather than the root cause — the type was misclassified earlier.
Related errors
- get element type
- non-array a value
- unexpected additive operation {:?}
- internal error: entered unreachable code
- unexpected integer size
AI-assisted analysis of rust-lang/rust@22057b88b0 (2026-08-03).
Data as JSON: /data/errors/a855d127e388b351.json.
Report an issue: GitHub.