Skip to content

Commit

Permalink
Fix the variances of HashMap and HashSet iterators
Browse files Browse the repository at this point in the history
  • Loading branch information
gereeter committed Mar 31, 2016
1 parent 285a40a commit 1639f2d
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 26 deletions.
30 changes: 13 additions & 17 deletions src/libstd/collections/hash/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use borrow::Borrow;
use cmp::max;
use fmt::{self, Debug};
use hash::{Hash, SipHasher, BuildHasher};
use iter::{self, Map, FromIterator};
use iter::FromIterator;
use mem::{self, replace};
use ops::{Deref, Index};
use rand::{self, Rng};
Expand Down Expand Up @@ -836,8 +836,7 @@ impl<K, V, S> HashMap<K, V, S>
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn keys<'a>(&'a self) -> Keys<'a, K, V> {
fn first<A, B>((a, _): (A, B)) -> A { a }
Keys { inner: self.iter().map(first) }
Keys { inner: self.iter() }
}

/// An iterator visiting all values in arbitrary order.
Expand All @@ -859,8 +858,7 @@ impl<K, V, S> HashMap<K, V, S>
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn values<'a>(&'a self) -> Values<'a, K, V> {
fn second<A, B>((_, b): (A, B)) -> B { b }
Values { inner: self.iter().map(second) }
Values { inner: self.iter() }
}

/// An iterator visiting all key-value pairs in arbitrary order.
Expand Down Expand Up @@ -992,9 +990,8 @@ impl<K, V, S> HashMap<K, V, S>
#[inline]
#[stable(feature = "drain", since = "1.6.0")]
pub fn drain(&mut self) -> Drain<K, V> {
fn last_two<A, B, C>((_, b, c): (A, B, C)) -> (B, C) { (b, c) }
Drain {
inner: self.table.drain().map(last_two),
inner: self.table.drain(),
}
}

Expand Down Expand Up @@ -1224,13 +1221,13 @@ pub struct IterMut<'a, K: 'a, V: 'a> {
/// HashMap move iterator.
#[stable(feature = "rust1", since = "1.0.0")]
pub struct IntoIter<K, V> {
inner: iter::Map<table::IntoIter<K, V>, fn((SafeHash, K, V)) -> (K, V)>
inner: table::IntoIter<K, V>
}

/// HashMap keys iterator.
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Keys<'a, K: 'a, V: 'a> {
inner: Map<Iter<'a, K, V>, fn((&'a K, &'a V)) -> &'a K>
inner: Iter<'a, K, V>
}

// FIXME(#19839) Remove in favor of `#[derive(Clone)]`
Expand All @@ -1246,7 +1243,7 @@ impl<'a, K, V> Clone for Keys<'a, K, V> {
/// HashMap values iterator.
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Values<'a, K: 'a, V: 'a> {
inner: Map<Iter<'a, K, V>, fn((&'a K, &'a V)) -> &'a V>
inner: Iter<'a, K, V>
}

// FIXME(#19839) Remove in favor of `#[derive(Clone)]`
Expand All @@ -1262,7 +1259,7 @@ impl<'a, K, V> Clone for Values<'a, K, V> {
/// HashMap drain iterator.
#[stable(feature = "drain", since = "1.6.0")]
pub struct Drain<'a, K: 'a, V: 'a> {
inner: iter::Map<table::Drain<'a, K, V>, fn((SafeHash, K, V)) -> (K, V)>
inner: table::Drain<'a, K, V>
}

enum InternalEntry<K, V, M> {
Expand Down Expand Up @@ -1397,9 +1394,8 @@ impl<K, V, S> IntoIterator for HashMap<K, V, S>
/// let vec: Vec<(&str, isize)> = map.into_iter().collect();
/// ```
fn into_iter(self) -> IntoIter<K, V> {
fn last_two<A, B, C>((_, b, c): (A, B, C)) -> (B, C) { (b, c) }
IntoIter {
inner: self.table.into_iter().map(last_two)
inner: self.table.into_iter()
}
}
}
Expand Down Expand Up @@ -1432,7 +1428,7 @@ impl<'a, K, V> ExactSizeIterator for IterMut<'a, K, V> {
impl<K, V> Iterator for IntoIter<K, V> {
type Item = (K, V);

#[inline] fn next(&mut self) -> Option<(K, V)> { self.inner.next() }
#[inline] fn next(&mut self) -> Option<(K, V)> { self.inner.next().map(|(_, k, v)| (k, v)) }
#[inline] fn size_hint(&self) -> (usize, Option<usize>) { self.inner.size_hint() }
}
#[stable(feature = "rust1", since = "1.0.0")]
Expand All @@ -1444,7 +1440,7 @@ impl<K, V> ExactSizeIterator for IntoIter<K, V> {
impl<'a, K, V> Iterator for Keys<'a, K, V> {
type Item = &'a K;

#[inline] fn next(&mut self) -> Option<(&'a K)> { self.inner.next() }
#[inline] fn next(&mut self) -> Option<(&'a K)> { self.inner.next().map(|(k, _)| k) }
#[inline] fn size_hint(&self) -> (usize, Option<usize>) { self.inner.size_hint() }
}
#[stable(feature = "rust1", since = "1.0.0")]
Expand All @@ -1456,7 +1452,7 @@ impl<'a, K, V> ExactSizeIterator for Keys<'a, K, V> {
impl<'a, K, V> Iterator for Values<'a, K, V> {
type Item = &'a V;

#[inline] fn next(&mut self) -> Option<(&'a V)> { self.inner.next() }
#[inline] fn next(&mut self) -> Option<(&'a V)> { self.inner.next().map(|(_, v)| v) }
#[inline] fn size_hint(&self) -> (usize, Option<usize>) { self.inner.size_hint() }
}
#[stable(feature = "rust1", since = "1.0.0")]
Expand All @@ -1468,7 +1464,7 @@ impl<'a, K, V> ExactSizeIterator for Values<'a, K, V> {
impl<'a, K, V> Iterator for Drain<'a, K, V> {
type Item = (K, V);

#[inline] fn next(&mut self) -> Option<(K, V)> { self.inner.next() }
#[inline] fn next(&mut self) -> Option<(K, V)> { self.inner.next().map(|(_, k, v)| (k, v)) }
#[inline] fn size_hint(&self) -> (usize, Option<usize>) { self.inner.size_hint() }
}
#[stable(feature = "rust1", since = "1.0.0")]
Expand Down
16 changes: 7 additions & 9 deletions src/libstd/collections/hash/set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
use borrow::Borrow;
use fmt;
use hash::{Hash, BuildHasher};
use iter::{Map, Chain, FromIterator};
use iter::{Chain, FromIterator};
use ops::{BitOr, BitAnd, BitXor, Sub};

use super::Recover;
Expand Down Expand Up @@ -414,8 +414,7 @@ impl<T, S> HashSet<T, S>
#[inline]
#[stable(feature = "drain", since = "1.6.0")]
pub fn drain(&mut self) -> Drain<T> {
fn first<A, B>((a, _): (A, B)) -> A { a }
Drain { iter: self.map.drain().map(first) }
Drain { iter: self.map.drain() }
}

/// Clears the set, removing all values.
Expand Down Expand Up @@ -809,13 +808,13 @@ pub struct Iter<'a, K: 'a> {
/// HashSet move iterator
#[stable(feature = "rust1", since = "1.0.0")]
pub struct IntoIter<K> {
iter: Map<map::IntoIter<K, ()>, fn((K, ())) -> K>
iter: map::IntoIter<K, ()>
}

/// HashSet drain iterator
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Drain<'a, K: 'a> {
iter: Map<map::Drain<'a, K, ()>, fn((K, ())) -> K>,
iter: map::Drain<'a, K, ()>,
}

/// Intersection iterator
Expand Down Expand Up @@ -889,8 +888,7 @@ impl<T, S> IntoIterator for HashSet<T, S>
/// }
/// ```
fn into_iter(self) -> IntoIter<T> {
fn first<A, B>((a, _): (A, B)) -> A { a }
IntoIter { iter: self.map.into_iter().map(first) }
IntoIter { iter: self.map.into_iter() }
}
}

Expand All @@ -914,7 +912,7 @@ impl<'a, K> ExactSizeIterator for Iter<'a, K> {
impl<K> Iterator for IntoIter<K> {
type Item = K;

fn next(&mut self) -> Option<K> { self.iter.next() }
fn next(&mut self) -> Option<K> { self.iter.next().map(|(k, _)| k) }
fn size_hint(&self) -> (usize, Option<usize>) { self.iter.size_hint() }
}
#[stable(feature = "rust1", since = "1.0.0")]
Expand All @@ -926,7 +924,7 @@ impl<K> ExactSizeIterator for IntoIter<K> {
impl<'a, K> Iterator for Drain<'a, K> {
type Item = K;

fn next(&mut self) -> Option<K> { self.iter.next() }
fn next(&mut self) -> Option<K> { self.iter.next().map(|(k, _)| k) }
fn size_hint(&self) -> (usize, Option<usize>) { self.iter.size_hint() }
}
#[stable(feature = "rust1", since = "1.0.0")]
Expand Down

0 comments on commit 1639f2d

Please sign in to comment.