The idea behind this trait is that it forces any type that implements the trait to also implement certain other traits. The thing is, after doing this, I find myself needing to write the following lines within implementations of generics that force their generics to implement the trait Currency, such as the following (it doesn't include all the traits that I am forcing, I now):
Why do I need to define those same dependencis again? It makes it a bit cumbersome to need to include double traits all the time. It is probably related to the fact that I don't need all the traits in the second code, but I would like to know why cannot we avoid the second declaration, what is left unclear.
I sure do wish we had implicit bound propagation, so that for a Foo<T: Bar>(T);
all impl blocks for it would get implicit bounds, so that you only needed to spell out impl<T> Foo<T> instead of impl<T: Bar> Foo<T>.
The sheer verbosity of manually propagating bounds everywhere is why we have silly things like:
let mut hmm: HashMap<f32, FrobnificationResult> = Default::default();
// ... elsewhere
fn<K> frobnify(m: &mut HashMap<K, Frob>, k: K, f: Frob) {
m.insert(k, f.frobnify()); // Error?? What?? Where? Why??
// Oh, right, having a `HashMap` doesn't mean it's usable,
// I need to propagate `K: Hash` bound upwards everywhere...
}
It's not really a bug as making all bounds implied would turn changes which are today backwards compatible into SemVer breaking changes, thus taking significant flexibility away from crate maintainers. AFAIC it's more of a lack of feature: the ability to opt in to implied bounds.[1]
The ability actually does exist for associated types, and there are some type system gymnastics one can perform around that, but it should be an intentional feature. ↩︎