-
Notifications
You must be signed in to change notification settings - Fork 13.3k
HashMap, HashSet: impl Hash #48366
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
HashMap, HashSet: impl Hash #48366
Changes from all commits
e6350e0
8c200ad
6f92790
e4dcd82
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1370,6 +1370,38 @@ impl<K, V, S> Eq for HashMap<K, V, S> | |
{ | ||
} | ||
|
||
#[unstable(feature = "hashmap_hash", issue = "0")] | ||
impl<K, V, S> Hash for HashMap<K, V, S> | ||
where K: Eq + Hash, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, it is necessary for |
||
V: Hash, | ||
S: BuildHasher | ||
{ | ||
fn hash<H: Hasher>(&self, hasher: &mut H) { | ||
// We must preserve: x == y -> hash(x) == hash(y). | ||
// HashMaps have no order, so we must combine the elements with an | ||
// associative and commutative operation • so that the order does not | ||
// matter. In other words, (u64, •, 0) must form a commutative monoid. | ||
// This is satisfied by • = u64::wrapping_add. | ||
// | ||
// We must further ensure that the hashing of individual elements does | ||
// not depend on the state of the given Hasher. So we ensure that | ||
// hashing each individual element starts with the same state. | ||
// | ||
// Unfortunately, we can't .clone() the hasher since we can't add more | ||
// constraints than H being a Hasher. With some sort of ConstraintKinds | ||
// we might be able do so in the future. | ||
hasher.write_u64( | ||
self.iter() | ||
.map(|kv| { | ||
let mut h = DefaultHasher::new(); | ||
kv.hash(&mut h); | ||
h.finish() | ||
}) | ||
.fold(0, u64::wrapping_add) | ||
dtolnay marked this conversation as resolved.
Show resolved
Hide resolved
|
||
); | ||
} | ||
} | ||
|
||
#[stable(feature = "rust1", since = "1.0.0")] | ||
impl<K, V, S> Debug for HashMap<K, V, S> | ||
where K: Eq + Hash + Debug, | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,7 +10,7 @@ | |
|
||
use borrow::Borrow; | ||
use fmt; | ||
use hash::{Hash, BuildHasher}; | ||
use hash::{Hash, Hasher, BuildHasher}; | ||
use iter::{Chain, FromIterator, FusedIterator}; | ||
use ops::{BitOr, BitAnd, BitXor, Sub}; | ||
|
||
|
@@ -757,6 +757,16 @@ impl<T, S> Eq for HashSet<T, S> | |
{ | ||
} | ||
|
||
#[unstable(feature = "hashmap_hash", issue = "0")] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. impls are insta-stable There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. hmm yes, true... maybe it should be |
||
impl<T, S> Hash for HashSet<T, S> | ||
where T: Eq + Hash, | ||
S: BuildHasher | ||
{ | ||
fn hash<H: Hasher>(&self, hasher: &mut H) { | ||
self.map.hash(hasher); | ||
dtolnay marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
} | ||
|
||
#[stable(feature = "rust1", since = "1.0.0")] | ||
impl<T, S> fmt::Debug for HashSet<T, S> | ||
where T: Eq + Hash + fmt::Debug, | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
impls are insta-stable