rust-lang/rust · error
non-array a value
Error message
non-array a value
What it means
In `CodegenCx::operation_with_overflow` (the helper invoked for non-`__builtin_*` overflow ops), the code asserts that `lhs`'s type is an array (the i128/u128-as-two-i64 representation) and recovers its element type via `dyncast_array().expect("non-array a value")`. If `lhs.get_type()` is not an array — e.g. a native int slipped through, or a pointer/aggregate — the expect fails.
Source
Thrown at compiler/rustc_codegen_gcc/src/int.rs:357
) -> (RValue<'gcc>, RValue<'gcc>) {
let a_type = lhs.get_type();
let b_type = rhs.get_type();
debug_assert!(a_type.dyncast_array().is_some());
debug_assert!(b_type.dyncast_array().is_some());
let overflow_type = self.i32_type;
let overflow_param_type = overflow_type.make_pointer();
let res_type = a_type;
let overflow_value =
self.current_func().new_local(self.location, overflow_type, "overflow");
let overflow_addr = overflow_value.get_address(self.location);
let param_a = self.context.new_parameter(self.location, a_type, "a");
let param_b = self.context.new_parameter(self.location, b_type, "b");
let param_overflow =
self.context.new_parameter(self.location, overflow_param_type, "overflow");
let a_elem_type = a_type.dyncast_array().expect("non-array a value");
debug_assert!(a_elem_type.is_integral());
let res_ty = match width {
32 => self.tcx.types.i32,
64 => self.tcx.types.i64,
128 => self.tcx.types.i128,
_ => unreachable!("unexpected integer size"),
};
let layout = self
.tcx
.layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(res_ty))
.unwrap();
let arg_abi = ArgAbi { layout, mode: PassMode::Direct(ArgAttributes::new()) };
let mut fn_abi = FnAbi {
args: vec![arg_abi.clone(), arg_abi.clone(), arg_abi.clone()].into_boxed_slice(),
ret: arg_abi,
c_variadic: false,
fixed_count: 3,View on GitHub (pinned to 22057b88b0)
Solutions
- Confirm `is_native_int_type(lhs.get_type())` returned false (otherwise `__builtin_*_overflow` should have been used instead).
- Dump `lhs.get_type()` to confirm whether it is really an array; if not, the classification helpers are wrong.
- Verify the i128/u128 array layout on this libgccjit version — `concat_low_high` and `dyncast_array` must agree.
- If a new non-array non-native type is legitimate, redesign `operation_with_overflow` rather than weakening the expect.
Example fix
// before
let a_elem_type = a_type.dyncast_array().expect("non-array a value");
// after
let a_elem_type = a_type.dyncast_array().unwrap_or_else(|| {
panic!("operation_with_overflow: lhs is not an i128/u128 array: {:?}", a_type);
}); Defensive patterns
Strategy: type-guard
Validate before calling
// operation_with_overflow requires lhs.get_type().dyncast_array().is_some().
let a_type = lhs.get_type();
if a_type.dyncast_array().is_none() {
return Err("operation_with_overflow: lhs type is not a gccjit array (expected i128/u128 emulation)");
}
builder.operation_with_overflow(func_name, lhs, rhs, width) Type guard
/// True when the value's gccjit type is the 2-element array used to
/// emulate a non-native integer (i128/u128 on 32-bit targets).
fn is_emulated_int_array<'gcc>(value: gccjit::RValue<'gcc>) -> bool {
value.get_type().dyncast_array().is_some()
}
if is_emulated_int_array(lhs) {
builder.operation_with_overflow(func_name, lhs, rhs, width)
} Prevention
- operation_with_overflow is the non-native overflow helper; only call it for i128/u128 values, which are represented as gccjit arrays on 32-bit targets.
- Build 128-bit constants through gcc_int/gcc_uint_big/concat_low_high so they carry the array type, not a raw scalar.
- Add a debug_assert!(a_type.dyncast_array().is_some()) at the entry of any helper that funnels into operation_with_overflow.
When it happens
Trigger: `operation_with_overflow` is called with an `lhs` whose GCC type is not the 2-element array used for non-native 128-bit ints. Reached from `gcc_checked_binop` after it has already chosen the non-`__builtin_*` path, so the type classification upstream (`is_native_int_type`) and the assertion here disagree.
Common situations: Same root family as 134–136: type-classification mismatch, custom ABI/target, or a refactor that changed the array representation of i128/u128. Often co-occurs with one of those.
Related errors
- element type
- get element type
- internal error: entered unreachable code
- unexpected integer size
- unexpected additive operation {:?}
AI-assisted analysis of rust-lang/rust@22057b88b0 (2026-08-03).
Data as JSON: /data/errors/4979e799c746a6fd.json.
Report an issue: GitHub.