From 84898e77427f0b3d22ddb77d24377d8773f2c068 Mon Sep 17 00:00:00 2001 From: varkor Date: Tue, 20 Feb 2018 01:34:28 +0000 Subject: [PATCH 1/2] Allow binary HashSet operations to be generic over hashers Allow the two sets that are parameters in `HashSet::{difference, intersection, is_disjoint, is_subset, is_superset}` to have different hashing algorithms. Fixes #31712. --- src/libstd/collections/hash/set.rs | 43 +++++++++++++++++++++--------- 1 file changed, 30 insertions(+), 13 deletions(-) diff --git a/src/libstd/collections/hash/set.rs b/src/libstd/collections/hash/set.rs index e9427fb40a016..cde932dbcc080 100644 --- a/src/libstd/collections/hash/set.rs +++ b/src/libstd/collections/hash/set.rs @@ -337,7 +337,7 @@ impl HashSet /// assert_eq!(diff, [4].iter().collect()); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - pub fn difference<'a>(&'a self, other: &'a HashSet) -> Difference<'a, T, S> { + pub fn difference<'a, U>(&'a self, other: &'a HashSet) -> Difference<'a, T, U> { Difference { iter: self.iter(), other, @@ -391,7 +391,7 @@ impl HashSet /// assert_eq!(intersection, [2, 3].iter().collect()); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - pub fn intersection<'a>(&'a self, other: &'a HashSet) -> Intersection<'a, T, S> { + pub fn intersection<'a, U>(&'a self, other: &'a HashSet) -> Intersection<'a, T, U> { Intersection { iter: self.iter(), other, @@ -565,7 +565,7 @@ impl HashSet /// assert_eq!(a.is_disjoint(&b), false); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - pub fn is_disjoint(&self, other: &HashSet) -> bool { + pub fn is_disjoint(&self, other: &HashSet) -> bool { self.iter().all(|v| !other.contains(v)) } @@ -587,7 +587,7 @@ impl HashSet /// assert_eq!(set.is_subset(&sup), false); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - pub fn is_subset(&self, other: &HashSet) -> bool { + pub fn is_subset(&self, other: &HashSet) -> bool { self.iter().all(|v| other.contains(v)) } @@ -613,7 +613,7 @@ impl HashSet /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - pub fn is_superset(&self, other: &HashSet) -> bool { + pub fn is_superset(&self, other: &HashSet) -> bool { other.is_subset(self) } @@ -1375,6 +1375,23 @@ fn assert_covariance() { mod test_set { use super::HashSet; use super::super::map::RandomState; + use hash::BuildHasher; + + struct AltRandomState(RandomState); + + impl AltRandomState { + fn new() -> AltRandomState { + AltRandomState(RandomState::new()) + } + } + + impl BuildHasher for AltRandomState { + type Hasher = ::Hasher; + + fn build_hasher(&self) -> Self::Hasher { + self.0.build_hasher() + } + } #[test] fn test_zero_capacities() { @@ -1410,8 +1427,8 @@ mod test_set { #[test] fn test_disjoint() { - let mut xs = HashSet::new(); - let mut ys = HashSet::new(); + let mut xs = HashSet::with_hasher(RandomState::new()); + let mut ys = HashSet::with_hasher(AltRandomState::new()); assert!(xs.is_disjoint(&ys)); assert!(ys.is_disjoint(&xs)); assert!(xs.insert(5)); @@ -1432,13 +1449,13 @@ mod test_set { #[test] fn test_subset_and_superset() { - let mut a = HashSet::new(); + let mut a = HashSet::with_hasher(RandomState::new()); assert!(a.insert(0)); assert!(a.insert(5)); assert!(a.insert(11)); assert!(a.insert(7)); - let mut b = HashSet::new(); + let mut b = HashSet::with_hasher(AltRandomState::new()); assert!(b.insert(0)); assert!(b.insert(7)); assert!(b.insert(19)); @@ -1474,8 +1491,8 @@ mod test_set { #[test] fn test_intersection() { - let mut a = HashSet::new(); - let mut b = HashSet::new(); + let mut a = HashSet::with_hasher(RandomState::new()); + let mut b = HashSet::with_hasher(AltRandomState::new()); assert!(a.insert(11)); assert!(a.insert(1)); @@ -1504,8 +1521,8 @@ mod test_set { #[test] fn test_difference() { - let mut a = HashSet::new(); - let mut b = HashSet::new(); + let mut a = HashSet::with_hasher(RandomState::new()); + let mut b = HashSet::with_hasher(AltRandomState::new()); assert!(a.insert(1)); assert!(a.insert(3)); From 2e55a0bc0e07ca43eddb3eae5d7422f40f69ae88 Mon Sep 17 00:00:00 2001 From: varkor Date: Wed, 28 Feb 2018 11:35:45 +0000 Subject: [PATCH 2/2] Explicate BuildHasher bound on difference and intersection --- src/libstd/collections/hash/set.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/libstd/collections/hash/set.rs b/src/libstd/collections/hash/set.rs index cde932dbcc080..4eeee54e11629 100644 --- a/src/libstd/collections/hash/set.rs +++ b/src/libstd/collections/hash/set.rs @@ -337,7 +337,9 @@ impl HashSet /// assert_eq!(diff, [4].iter().collect()); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - pub fn difference<'a, U>(&'a self, other: &'a HashSet) -> Difference<'a, T, U> { + pub fn difference<'a, U: BuildHasher>(&'a self, + other: &'a HashSet) + -> Difference<'a, T, U> { Difference { iter: self.iter(), other, @@ -391,7 +393,9 @@ impl HashSet /// assert_eq!(intersection, [2, 3].iter().collect()); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - pub fn intersection<'a, U>(&'a self, other: &'a HashSet) -> Intersection<'a, T, U> { + pub fn intersection<'a, U: BuildHasher>(&'a self, + other: &'a HashSet) + -> Intersection<'a, T, U> { Intersection { iter: self.iter(), other,