Although due to the lack of #[cfg(overflow_checks)]
it would need a compiler intrinsic (I believe).
At least in part because it would break inference.
x + 0
works today because there's only one option.
If you add impl Add<i8> for u8
, then x + 0
will end up hitting i32
fallback for the 0
, and thus it'll be u8 + i32
, and not exist.
(It's also possible that people intentionally don't want the mixing, and prefer seeing that the types are different.)
Although I would like to take this opportunity to say that I strongly support an overflow_checks
cfg for custom numeric types.
Add
isn't guaranteed to check, so existence of the checked method is not really helping.
Of course the behavior wouldn't be worse than Sub<u64>
, but implicit numeric type conversions are a bit of a taboo topic for Rust. There are a lot of users here burned by C's reckless behavior who will not want to hear about any proposal even slightly in that direction.
-
There isn’t a method version of panicking addition either—what I was saying is that implementing
Add<i64> for u64
would be possible given thatchecked_add_signed
exists. -
I’m not saying anything about implicit type conversion—if
impl Add<i64> for u64
existed it wouldn’t be an implicit type conversion.
Is this what you had in mind then?
impl Add<i64> for u64 {
type Output = Option<u64>;
fn add(self, other: i64) -> Self::Output {
self.checked_add_signed(other)
}
}
And is there a benefit besides typing less? Some drawbacks are
- less visibly obvious / principle of least suprise
- still breaks inference like @scottmcm said; so much code would break that nothing like this will land unless the inference algorithm itself changes
No. What I was saying would be impossible to implement currently without a compiler intrinsic or #[cfg(overflow_checks)]
. With that, it’d go like this:
impl Add<i64> for u64 {
type Output = u64;
#[cfg(overflow_checks)]
fn add(self, other: i64) -> u64 {
self.checked_add_signed(other).expect("attempt to add with overflow")
}
#[cfg(not(overflow_checks))]
fn add(self, other: i64) -> u64 {
self.wrapping_add_signed(other)
}
}
This is perfectly analogous to other addition implementations.
In that case it's effectively an implicit conversion when it doesn't panic and the cultural pushback will still happen, even if the inference story changes.
…it’s an implicit conversion with a change to how overflow is detected, though. But yes, the inference is a blocker.