e.g. I don't necessarily have a use for an integer from 0 to 11, but I do see a use for BalancedI8, a one byte type with values -127 to +127 via 0, thus omitting -128. I reckon lots of people don't need -128, whereas a niche is very useful. Rust provides NonZeroI8, which has -128 through +127 but no zero, but I find that's less often what you want, and it's not today possible to make your own in stable Rust (and in nightly Rust you need a not-for-mortals perma-unstable attribute today).
Of course that doesn't scale to larger types as even with a macro the compile speed will be horrible.
Today, in practice, if you want BalancedI32 what you'd do is swizzle NonZeroI32, so that a trivial CPU operation converts between the two types and you can deliver almost the same optimisations in practice. But, I think that's also pretty ugly, and Rust clearly could do the nicer thing here, indeed it does in my crate that only builds on nightly and is using not-for-public-use compiler internal attributes. So that's what I want, just apparently not enough to spend my vacation time last month working on it. Maybe next month.
Yes. Ada supports integral types with custom ranges:
https://learn.adacore.com/courses/intro-to-ada/chapters/stro...