ADR-315: Arithmetic and a Conversion That May Not Fit Can Be Asked Whether They Do — checked_ Names, With the Answer Optional

Status: Accepted Date: October 4, 2026 Answers: the owner’s question, after the build-time evaluator’s integers left i128 (0.0.416), whether the places where the compiler reached for a wider number out of convenience would read better with a name for the alternative - where the uses overlap Related: ADR-285 D1 (an overflow aborts), D4 (a conversion that may not fit aborts), D6-D7 (wrapping and saturating have names, not operators), D13 (truncation has a name that carries its destination); ADR-294 D11 (an integer while the program is built is a magnitude and a sign); Part I 2.3 (T? and ??)

1. Question

Nikaia has three things to say about an integer operation whose answer does not fit: abort (+, as, D1 and D4), wrap (wrapping_add, D6) and stop at the limit (saturating_add, D6), plus keeping the low digits of a conversion (truncating_i32, D13). It has no way to ask - to get the answer where there is one and to find out, as a value, where there is none.

The compiler’s own Nikaia shows what that costs. Where it asks, it asks by hand:

And the Rust that is still to move asks the same question about twenty-five times (i32::try_from(v).is_ok(), checked_add), which is how i128 got in: compute wide, then compare. Moving that Rust means writing each of those again by hand, or having the name.

2. How others do it

The optional is the common answer for the conversion (Swift, Zig, Rust’s .ok()), and Rust’s own checked_ names are the optional for the arithmetic.

3. Options, weighed

Option For Against
A. Leave it to the program (Go) Nothing to add The five hand-made checks above stay, and every Rust site that moves adds one
B. An operator (a +? b) Short D6 already said no to an operator for the other two families, for the reason that holds here: rare, and worth seeing by name
C. checked_ names with a T? answer, and checked_<type>() conversions One more family in the pattern D6, D7 and D13 set; ?? already reads an optional; Rust’s own names, so the lowered code is idiomatic Thirty-three ledger entries
D. A Result with an error (Rust’s try_from) Says why There is one reason - it does not fit - and an error type for one reason is ceremony

4. Decision

Option C.

D1 — checked_add, _sub, _mul, _div, _rem, _neg and _abs answer T?.

a.checked_add(b) is the sum where it fits and null where it does not, for i32, i64, u8, u32 and u64 - the types D6’s names exist for (u8 by ADR-285 D41). An unsigned type has no _neg and no _abs, as it has no wrapping_neg.

let sum = a.checked_add(b) ?? return null

D2 — A division by zero is null too.

checked_div and checked_rem answer null for a divisor of zero as well as for the one quotient that overflows (the most negative number by -1). Unlike wrapping_div, which still aborts on zero (D6), a name that asks whether there is an answer gets one for every input: there is no quotient by zero, and saying so is what the name is for.

D3 — No checked_shl and no checked_shr.

Rust’s ask whether the count is inside the width, not whether the bits that leave were zero. A name saying checked over a shift that still loses digits would claim more than it does; a program that wants the second asks it with a multiplication.

D4 — checked_i32(), checked_i64(), checked_u8(), checked_u32() and checked_u64() answer the destination, optional.

n.checked_i32() is n as an i32 where an i32 holds it and null where it does not - the conversion D4 of ADR-285 aborts on, asked instead. The destination is in the name, as it is for truncating_ (D13), and for the same reason: one ledger entry per destination. They exist only out of a type that has values the destination lacks; a widening always fits and is written as. An f64 has none of them: a float’s conversion is not a range question alone.

D5 — They lower to Rust’s own.

The arithmetic is Rust’s checked_add and the rest by name; a conversion is <T>::try_from(n).ok(). Neither can abort, and neither leans on overflow-checks.

5. Consequences

6. What this does not decide

This site is open source. Improve this page.