I'm trying to unify the use of math ops on newtypes which may or may not be Copy
(or trying to avoid having to implement the same function twice as a + b * c
and &a + &b * &c
).
Implementing ops like Add
for Copy
newtypes is easy and you can get away with just doing it for owned types. On the other hand, for non-Copy
types you need to do it for &Self and both RHS or &RHS.
I think implementing Deref
on the newtype simplifies this some through the tuple field access, but may make the newtype too easily coerced to its inner type. Which leaves AsRef
/Borrow
or a custom inner function as the best bet for unifying things:
trait NewtypeInner<'a> {
type Inner;
fn inner(&'a self) -> Self::Inner;
}
impl<'a, T: Copy> NewtypeInner<'a> for Newtype<T> {
type Inner = T;
fn inner(&'a self) -> Self::Inner { self.0 }
}
And perhaps from there it's just a matter of carefully implementing the right Newtypes with NewtypeInner::Inner
types which have the right implementations? But I seem to be running into lifetime issues (playground link)
Am I on the right track? Does anyone have any insights or wisdom to share on this?