Per https://github.com/rust-lang/rust/issues/8634, I can sort-of create an alias for some traits:
pub trait Addable: Add<Output=Self> + Debug + Sized + Clone {}
impl<T: Add<Output=T> + Debug + Sized + Clone> Addable for T {}
pub struct Showoff<T> { a: T, b: T }
impl<T: Addable> Showoff<T> {
pub fn sum(&self) -> T { self.a.clone() + self.b.clone() }
}
fn main() {
let showoff = Showoff { a: 1, b: 2 };
println!("sum: {}", showoff.sum());
}
This works pretty good. Essentially, T: Addable
currently is an alias for T: Add<Output=T>
plus some other stuff.
The need to clone bothers me, though: as an example, it seems like a Showoff<isize>
is doing some unnecessary copies. What I'd like is for T: Addable
to also be an alias for &T: Add<Output=T>
. Then I wouldn't have to clone:
pub trait Addable<'a>: Add<Output=Self> + Debug + Sized
where Self: 'a, &'a Self: Add<Output=Self> {}
impl<'a, T: Add<Output=T> + Debug + Sized> Addable<'a> for T
where T: 'a, &'a T: Add<Output=T> {}
pub struct Showoff<T> { a: T, b: T }
impl<'a, T: Addable<'a>> Showoff<T> {
pub fn sum(&'a self) -> T { &self.a + &self.b }
}
However, rustc
doesn't compile, complaining that impl Showoff
doesn't satisfy &T: Add
. It seems like T: Addable
carries the T: Add<...>
bounds with it, but not the &T: Add<...>
bounds, forcing me to repeat it on all its impls:
impl<'a, T: Addable<'a>> Showoff<T> where T: 'a, &'a T: Add<Output=T> {...}
which somewhat negates the reason I'm trying to create an alias in the first place.
Does anyone have an idea how to accomplish what I'm trying to do here? It feels like implementation bounds on a trait should carry all the bounds of that trait, but perhaps I'm missing something. It's not a huge deal: basically just more typing, but any help or insight here would be appreciated.