This would be useful in cases were you want to use / store a number but don't care about a specific type of number for example:
/// add two integers together
pub fn add<T: PrimitiveInt>(x: T, y: T) -> T {
x + y
}
This could also be useful for implementing arithmetic operations between primitive ints and "big int" structs:
use std::ops::Add;
struct BigInt {/* */}
impl<T: PrimitiveInt> Add for BigInt {
// ...
}
And I am aware of solutions provided by for example the num crate.
I still however think that this should be added to the stdlib, because there have been over 200 million downloads of the num crate and there are perhaps people that only use the crate for this specific trait.
Implementing it would be very easy as it is basically just one huge super-trait that covers all trait which a primitive int implements.
Obligatory link to https://github.com/rust-lang/rfcs/pull/3686 which I like because it'll let you do impl<const N: u32> MyTrait for u<N> { ... } or fn my_fn<const N: u32>(i: u<N>), which I think actually covers things better than a trait would because it doesn't have the same coherence problems.
See also num-primitive, which goes well beyond the core num crates by adding all stable functionality that it can for all primitive numeric types. Funny though, it didn't occur to me to start using that in num-bigint for it's primitive interactions, but we probably could!
Wait does the num crate really define big int - primitive interactions per primitive? Wouldn’t it be better if they used their own primitive int trait?
That's a blanket impl, so you typically can't actually implement MyTrait in any other way -- after all, for all the compiler knows, any type on which you might implement it could also implement MagicNewNumTrait in the future.
That's one reason why first-class trait sealing would be nice, so the compiler could know that any type downstream of the trait will never implement it.
Yeah, I agree coherence-aware sealing would be interesting -- though complex since the local impls might themselves be dependent on external traits -- for lots of things.
But even if we had that, I still like impl<N> MyTrait for u<N> better. If nothing else because it doesn't also need mutually-exclusive traits to be able to also impl<N> MyTrait for i<N>.
We're planning to add numeric traits in the standard library once we have library trait evolution, so that we're confident we will be able to fix and extend those traits.
because usize is never the same type as u32, u64, etc. even if they have the same signedness and bit width and ABI. Rust currently guarantees you can impl traits differently for them and that doesn't work if usize is just a type alias.