slint-ui/slint · error
attempt to multiply with overflow
Error message
attempt to multiply with overflow
What it means
The software renderer's fixed-point `Fixed::mul` widens both operands to `i64`, multiplies, shifts right by `SHIFT`, and converts back with `try_from().expect()`. The panic fires when the product (before or after the shift) cannot be represented in the underlying `T` (e.g. `i16`/`i32` fixed-point), i.e. an arithmetic overflow in fixed-point math. Rust's debug build turns the intermediate `lhs * rhs` multiply into its own 'attempt to multiply with overflow' panic if the i64 product itself overflows (extremely large operands).
Solutions
- Check the geometry/transform values feeding the renderer — clamp item sizes and scale factors to sane ranges
- Run in release mode (`--release`) where debug overflow assertions on the i64 multiply are off (the `try_from` still panics on T overflow)
- Upgrade Slint — fixed-point overflow handling may have been widened or made saturating
- Reduce window size / scaling factor (e.g. very large HiDPI multipliers) that push coordinates out of range
Example fix
// before (library code)
Self(T::try_from((lhs_i64 * rhs_i64) >> SHIFT).expect("attempt to multiply with overflow"))
// after (saturating alternative)
Self(T::try_from(((lhs_i64 * rhs_i64) >> SHIFT)).unwrap_or(T::MAX)) Defensive patterns
Strategy: validation
Validate before calling
// keep geometry within fixed-point range before layout debug_assert!(w < 1_000_000 && h < 1_000_000, "geometry out of fixed-point range");
Prevention
- Clamp item sizes, offsets, and scale factors to realistic ranges
- Avoid extreme HiDPI scale multipliers with the software renderer
- Keep overflow-check behavior in mind: test debug builds to surface overflow early
- Upgrade Slint if you legitimately need larger coordinate ranges
When it happens
Trigger: Multiplying two `Fixed<T, SHIFT>` values whose product exceeds `T`'s range after shifting — e.g. multiplying large layout coordinates or scale factors in the software renderer; also triggered in debug builds when `(lhs_i64 * rhs_i64)` overflows `i64` (operands near `i64::MAX`).
Common situations: Software-renderer users hit this with pathological geometry: enormous item sizes/offsets, huge scale transforms, or window coordinates in the billions; more common in debug builds where overflow checks are on.
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
Related errors
- a setter belongs to a field
- an identifier
- binding was of the wrong type
- Called a not-implemented method
- Cannot get property
AI-assisted analysis of slint-ui/slint@bb937076de (2026-09-16).
Data as JSON: /api/errors/09b49b2e46c93813.
Report an issue: GitHub.
Appendix: source
Thrown at internal/renderers/software/fixed.rs:130
impl<T: core::ops::Mul<Output = T>, const SHIFT: usize> core::ops::Mul<T> for Fixed<T, SHIFT> {
type Output = Self;
#[inline(always)]
fn mul(self, rhs: T) -> Self::Output {
Self(self.0.mul(rhs))
}
}
impl<T: core::ops::Mul<Output = T>, const SHIFT: usize> core::ops::Mul<Fixed<T, SHIFT>>
for Fixed<T, SHIFT>
where
T: TryFrom<i64> + Into<i64>,
<T as TryFrom<i64>>::Error: core::fmt::Debug,
{
type Output = Self;
fn mul(self, rhs: Fixed<T, SHIFT>) -> Self::Output {
let lhs_i64: i64 = self.0.into();
let rhs_i64: i64 = rhs.0.into();
Self(T::try_from((lhs_i64 * rhs_i64) >> SHIFT).expect("attempt to multiply with overflow"))
}
}
impl<T: core::ops::Neg<Output = T>, const SHIFT: usize> core::ops::Neg for Fixed<T, SHIFT> {
type Output = Self;
#[inline(always)]
fn neg(self) -> Self::Output {
Self(-self.0)
}
}
impl<T: core::ops::Div<Output = T>, const SHIFT: usize> core::ops::Div for Fixed<T, SHIFT> {
type Output = T;
#[inline(always)]
fn div(self, rhs: Self) -> Self::Output {
self.0 / rhs.0
}
}View on GitHub (pinned to bb937076de)