There's a lot of unnecessary trait bounds in HashMap that could be pruned.
Examples:
impl Default for HashMap<K, V, S> really only needs S: Default
impl Debug for HashMap<K, V, S> really only needs K: Debug and V: Debug
- Many of the methods only require one out of
K: Eq + Hash or S: BuildHasher, or sometimes neither.
Most of this isn't a big deal, but for Default and Debug this is a nuisance because you can't use #[derive(Debug, Default)] on unconstrained types containing HashMap, e.g.
// won't compile
#[derive(Debug, Default)]
struct MyStruct<K>(HashMap<K>);
// your options are to either:
//
// - needlessly constrain `K` directly on the struct itself,
// which then infects everything involving MyStruct
// - define Debug and Default manually with the redundant constraints;
// downstream types that contain MyStruct are still screwed
One might argue that this would limit potential implementations, but for a lot them like Default or .len(), no sensible implementation should ever use K: Eq + Hash at all.
This also applies to BTreeMap to some extent (Default doesn't need Ord, for example).
Patch: Rufflewind@a1587a1
There's a lot of unnecessary trait bounds in
HashMapthat could be pruned.Examples:
impl Default for HashMap<K, V, S>really only needsS: Defaultimpl Debug for HashMap<K, V, S>really only needsK: DebugandV: DebugK: Eq + HashorS: BuildHasher, or sometimes neither.Most of this isn't a big deal, but for
DefaultandDebugthis is a nuisance because you can't use#[derive(Debug, Default)]on unconstrained types containingHashMap, e.g.One might argue that this would limit potential implementations, but for a lot them like
Defaultor.len(), no sensible implementation should ever useK: Eq + Hashat all.This also applies to
BTreeMapto some extent (Defaultdoesn't needOrd, for example).Patch: Rufflewind@a1587a1