Summary
Add support for deriving Add, Sub, Mul and Div on structs whose fields implement them.
EDIT: Here we are talking about Rhs=Self implementation.
Rationale
In Rust, implementing arithmetic traits like Add, Sub, Mul, or Div requires either manually writing implementation or dependency on third-party crates like derive_more even for trivial cases where the semantics are unambiguous (e.g. field-wise operations on numeric structs).
#[derive(Add)]
struct Point(u32, u32); // a + b == Point(a.0 + b.0, a.1 + b.1)
This is pointless busywork when the only sensible behavior is to perform the operation field by field. It would work the same way Clone, Debug and Copy is resolved.
Generics?
For generic structs like:
#[derive(Add)]
struct Point<T> {
x: T,
y: T,
}
the derived implementation automatically requires T: Add (exactly like #[derive(Clone)] requires T: Clone ).
What about enums?
I noticed that enums rarely need arithmetic and when they do, manual impls are clearer so this proposal intentionally excludes support for deriving arithmetic traits on enums. While third-party crates like derive_more offer a solution for enums - wrap the output in Result<Self, Error>.
impl Add for FooBar {
type Output = Result<Self, Error>;
fn add(self, rhs: Self) -> Self::Output {
match (self, rhs) {
(Foo(a), Foo(b)) => Ok(Foo(a + b)),
(Bar(a), Bar(b)) => Ok(Bar(a + b)),
_ => Err(Error::Mismatch),
}
}
}
Drawbacks
Adding a solution to the standard library that is necessarily more limited will create a small split in the ecosystem: "Should I use the standard derive or the more powerful derive_more ?"
Nevertheless, I decided to propose it, especially since the #[derive(From)] RFC has recently reached implementation so ÂŻ\_(ă)_/ÂŻ.
Unresolved Questions
Overflow behavior
Should derived implementations panic on overflow? The std's arithmetic traits provide no overflow control