rust-lang/rust · error
internal error: entered unreachable code
Error message
internal error: entered unreachable code
What it means
Inside `gcc_checked_binop`, on the non-native-int path for `OverflowOp::Add`, the match on `new_kind` only arms `Int(I128)` and `Uint(U128)` (mapping to `__rust_i128_addo`/`__rust_u128_addo`). Any other width reaching this branch is unreachable: on a platform where the int is non-native, only i128/u128 qualify; i8–i64 are expected to be native and use `__builtin_add_overflow`.
Source
Thrown at compiler/rustc_codegen_gcc/src/int.rs:299
Int(t @ Isize) => Int(t.normalize(self.tcx.sess.target.pointer_width)),
Uint(t @ Usize) => Uint(t.normalize(self.tcx.sess.target.pointer_width)),
t @ (Uint(_) | Int(_)) => t,
_ => panic!("tried to get overflow intrinsic for op applied to non-int type"),
};
// FIXME(antoyo): remove duplication with intrinsic?
let name = if self.is_native_int_type(lhs.get_type()) {
match oop {
OverflowOp::Add => "__builtin_add_overflow",
OverflowOp::Sub => "__builtin_sub_overflow",
OverflowOp::Mul => "__builtin_mul_overflow",
}
} else {
let (func_name, width) = match oop {
OverflowOp::Add => match new_kind {
Int(I128) => ("__rust_i128_addo", 128),
Uint(U128) => ("__rust_u128_addo", 128),
_ => unreachable!(),
},
OverflowOp::Sub => match new_kind {
Int(I128) => ("__rust_i128_subo", 128),
Uint(U128) => ("__rust_u128_subo", 128),
_ => unreachable!(),
},
OverflowOp::Mul => match new_kind {
Int(I32) => ("__mulosi4", 32),
Int(I64) => ("__mulodi4", 64),
Int(I128) => ("__rust_i128_mulo", 128), // FIXME(antoyo): use __muloti4d instead?
Uint(U128) => ("__rust_u128_mulo", 128),
_ => unreachable!(),
},
};
return self.operation_with_overflow(func_name, lhs, rhs, width);
};
let intrinsic = self.context.get_builtin_function(name);View on GitHub (pinned to 22057b88b0)
Solutions
- Verify `is_native_int_type` against the target pointer width: i8/i16/i32/i64 must be native on 64-bit, i8/i16/i32 on 32-bit.
- Dump `lhs.get_type()` and `new_kind` at the call to confirm which one is wrong.
- If a genuinely non-native width is needed (e.g. non-native i64), add an arm with the correct compiler-rt symbol (`__mulosi4`-style for add).
- Add a target-specific test for the platform that triggered it.
Example fix
// before
OverflowOp::Add => match new_kind {
Int(I128) => ("__rust_i128_addo", 128),
Uint(U128) => ("__rust_u128_addo", 128),
_ => unreachable!(),
},
// after
OverflowOp::Add => match new_kind {
Int(I128) => ("__rust_i128_addo", 128),
Uint(U128) => ("__rust_u128_addo", 128),
other => unreachable!("non-native add overflow for unexpected kind {:?}", other),
}, Defensive patterns
Strategy: fallback
Validate before calling
// Non-native overflow Add is only implemented for i128/u128 (width 128).
// If lhs is non-native but the resolved kind is not 128-bit, route elsewhere.
use rustc_middle::ty::{IntTy::*, UintTy::*, Int, Uint};
let native = builder.is_native_int_type(lhs.get_type());
let width_ok = match *typ.kind() {
Int(I128) | Uint(U128) => true,
_ => native, // native ints use __builtin_add_overflow and are fine
};
if !width_ok {
return Err("overflow Add: gcc backend only emulates i128/u128; rebuild with LLVM backend");
} Try / catch
// gcc backend panics on non-native overflow Add for non-128 widths.
// Catch the unwind and retry compilation with the LLVM backend.
use std::panic::{catch_unwind, AssertUnwindSafe};
let res = catch_unwind(AssertUnwindSafe(|| {
builder.gcc_checked_binop(OverflowOp::Add, typ, lhs, rhs)
}));
match res {
Ok(v) => v,
Err(_) => {
eprintln!("gcc backend cannot emulate overflow Add for {:?}; falling back to LLVM");
rebuild_with_backend("llvm")?;
}
} Prevention
- Overflow-Add emulation on the gcc backend is restricted to 128-bit non-native ints; avoid checked_add on exotic widths when targeting 32-bit platforms with -Ccodegen-backend=gcc.
- When in doubt about a width, compile the offending crate with the LLVM backend (drop -Ccodegen-backend=gcc) instead of patching around the panic.
- Unit-test new integer widths against gcc_checked_binop in Release before shipping; debug builds hide unreachable! behind the optimizer.
When it happens
Trigger: `is_native_int_type(lhs.get_type())` returns false for a type whose `new_kind` is not `I128`/`U128` (e.g. an i64 wrongly classified as non-native). The contradiction between type classification and width trips the unreachable.
Common situations: Misclassification of an integer's native-ness for the current target pointer width (32-bit target treating i64 as non-native, or a custom ABI). Also appears after changes to `is_native_int_type` that desync from the `new_kind` derivation.
Related errors
- non-array a value
- unexpected integer size
- element type
- get element type
- unexpected additive operation {:?}
AI-assisted analysis of rust-lang/rust@22057b88b0 (2026-08-03).
Data as JSON: /data/errors/31e5204359c0cc60.json.
Report an issue: GitHub.