External Publication
Visit Post

Infinite precision intermediate arithmetic: how much would break?

Rust Internals [Unofficial] June 8, 2026
Source

jdahlstrom:

This is, btw, essentially what C does

Besides what @jrose already said about this, there is a huge practical difference between "only goes up to [some fixed-length type]" and actually going to infinity in both directions. For example, in C comparisons between signed and unsigned values silently do the Wrong Thing, and in Rust (as it is now)

pub fn isless(a: i32, b: u32) -> bool {
    a < b
}

fails to compile but the suggested fix does not produce code that computes the mathematically correct answer. Under my proposal this would be equivalent to

pub fn isless(a: i32, b: u32) -> bool {
    // a u32 value that doesn't fit in i32 must be greater than all
    // possible i32 values
    i32::try_from(b).map(|ib| a < ib).unwrap_or(true)
}

chrefr:

Widening integer operations to i/u128 makes them way more expensive; widening float operations to ℝ will require extremely costly software calculations.

It is my hope that the same proofs of non-overflow that are required anyway can also be used to prove that register-sized calculations are correct in most cases. We would presumably have to relax the principle somewhat for transcendental functions, because of the Table-Maker's Dilemma.

promotion rules are deeply unintuitive and confusing, and the vast majority of developers never understand them well

I am explicitly claiming, as part of this proposal, that the rule "all calculations behave as-if they were carried out in the mathematical real numbers, and then, if the result doesn't always fit in the type of the target variable, you have to say what should happen for the edge cases" will be much easier to understand. I believe this claim because that rule is already basically what high-level interpreted languages like Python and Lisp do, and you never hear about people struggling with their promotion rules.

Also, there are no implicit narrowing conversions under this proposal. Only situations where the compiler can prove that no conversion is required.

jdahlstrom:

Realistically, this proposal hinges on the ability of the compiler to prove non-overflow in "typical uses", and that would require importing a lot of machinery to the front end from LLVM, be difficult to write a specification for, and would probably fail often enough that people would get massively frustrated

This is a legit concern but I think a forward-only value range propagation pass, using rules like what we already have for whether it's OK to write "let blah;" with no initializer, will probably be good enough and not too much hassle to specify or implement. Whether I'm right, probably requires actually trying it to answer. (Java's "definite assignment" rules are also in the same ballpark and are, at least, not an undue burden on implementations; I cannot say whether people who've written a lot of Java find them annoying, though.)

Discussion in the ATmosphere

Loading comments...