rust-lang/rust · error · B::Error
Value overflow: cannot convert `{value}` to `{ty_internal}`.
Error message
Value overflow: cannot convert `{value}` to `{ty_internal}`. What it means
Thrown by `try_new_const_uint` in compiler/rustc_public_bridge/src/context/impls.rs:520 when a `u128` value does not fit into the target integer type's bit width. The bridge computes the type's layout size and calls `ScalarInt::try_from_uint(value, size)`; if the value exceeds the type's maximum (e.g. 256 into a `u8`), the conversion returns `None` and the error is raised. This guards against silent truncation when materializing an unsigned integer constant.
Source
Thrown at compiler/rustc_public_bridge/src/context/impls.rs:520
}
/// Create a new constant that represents the given boolean value.
pub fn new_const_bool(&self, value: bool) -> MirConst<'tcx> {
MirConst::from_bool(self.tcx, value)
}
pub fn try_new_const_uint(
&self,
value: u128,
ty_internal: Ty<'tcx>,
) -> Result<MirConst<'tcx>, B::Error> {
let size = self
.tcx
.layout_of(self.fully_monomorphized().as_query_input(ty_internal))
.unwrap()
.size;
let scalar = ScalarInt::try_from_uint(value, size).ok_or_else(|| {
B::Error::new(format!("Value overflow: cannot convert `{value}` to `{ty_internal}`."))
})?;
Ok(self.mir_const_from_scalar(Scalar::Int(scalar), ty_internal))
}
pub fn try_new_ty_const_uint(
&self,
value: u128,
ty_internal: Ty<'tcx>,
) -> Result<ty::Const<'tcx>, B::Error> {
let size = self
.tcx
.layout_of(self.fully_monomorphized().as_query_input(ty_internal))
.unwrap()
.size;
let scalar = ScalarInt::try_from_uint(value, size).ok_or_else(|| {
B::Error::new(format!("Value overflow: cannot convert `{value}` to `{ty_internal}`."))
})?;
View on GitHub (pinned to 22057b88b0)
Solutions
- Bounds-check the value against the target type's maximum (`1u128 << (8 * size.bytes()) - 1`) before calling.
- If the value legitimately needs more bits, widen the target type (e.g. `u8` -> `u32`) to fit it.
- Clamp or reject out-of-range values upstream in the data source.
Example fix
// before let c = cx.try_new_const_uint(value, ty_u8)?; // after let max = (1u128 << (8 * size_bytes)) - 1; let c = cx.try_new_const_uint(value.min(max), ty_u8)?;
Defensive patterns
Strategy: validation
Validate before calling
// Before MirConst::try_from_uint(value, uint_ty):
// NOTE: the internal impl does layout_of(...).unwrap() (impls.rs:517), so a
// non-computable layout PANICS before the overflow check. Compute the layout
// yourself first, then range-check the value.
let layout = ty.layout()?; // surfaces layout errors safely
let size = layout.shape().size; // MachineSize
let max = size.unsigned_int_max()
.ok_or_else(|| format!("{:?} is wider than 128 bits", ty))?;
if value > max {
return Err(format!("value {} overflows {:?} (max {})", value, ty, max));
}
let c = MirConst::try_from_uint(value, uint_ty)?; Try / catch
// try_from_uint returns Result for overflow, but PANICS on layout failure,
// so wrap untrusted types in catch_unwind as a last line of defense:
match std::panic::catch_unwind(|| MirConst::try_from_uint(value, uint_ty)) {
Ok(Ok(c)) => c,
Ok(Err(e)) if e.to_string().contains("Value overflow") => {
// Clamp or reject the value; do NOT retry unchanged.
return MirConst::try_from_uint(value.clamp(0, max_for(uint_ty)?), uint_ty);
}
Ok(Err(e)) => return Err(e.into()),
Err(_) => return Err(format!("layout of {:?} could not be computed", uint_ty)),
} Prevention
- Range-check the value against the target uint width: `value <= size.unsigned_int_max()` where size comes from `ty.layout()`; `u8` max is 255, `u64` max is 2^64-1, etc.
- The internal `layout_of(...).unwrap()` can PANIC for generic/unsized types — always call `Ty::layout()?` first so the layout error is a `Result`, not a panic.
- For `usize`, the max depends on the target pointer width (`target_pointer_width()`); do not assume 64-bit when cross-compiling.
- Prefer `MirConst::try_from_uint` (fallible) over any constructor that assumes a width; never widen a `u128` into a narrower type without this check.
When it happens
Trigger: Calling `context.try_new_const_uint(value, ty)` where `value` exceeds the type's range — e.g. `try_new_const_uint(256, u8_ty)`, `try_new_const_uint(u128::MAX, u16_ty)`. Feeding externally sourced `u128` values into typed const construction without bounds-checking.
Common situations: Deserializing constants from JSON/external data where the value width is not validated against the target type. Mismatched target type (passing `u8_ty` when the value needs `u32`). Off-by-one or inclusive-bound bugs in value generation.
Related errors
- Const `{cnst:?}` cannot be encoded as u64
- Cannot create a zero-sized constant for type `{ty_internal}`
- Cannot create a zero-sized constant for type `{ty_internal}`
- 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/fbc2c2bdbe79e597.json.
Report an issue: GitHub.