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

  1. Check the geometry/transform values feeding the renderer — clamp item sizes and scale factors to sane ranges
  2. Run in release mode (`--release`) where debug overflow assertions on the i64 multiply are off (the `try_from` still panics on T overflow)
  3. Upgrade Slint — fixed-point overflow handling may have been widened or made saturating
  4. 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

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


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)