Skip to content

Commit 53498ec

Browse files
committed
Auto merge of #32635 - gereeter:hashmap-iter-variance, r=alexcrichton
Make HashMap, HashSet, and their iterators properly covariant See #30642. `Drain` is the only type left invariant.
2 parents 3b342fa + 589108b commit 53498ec

File tree

3 files changed

+72
-44
lines changed

3 files changed

+72
-44
lines changed

src/libstd/collections/hash/map.rs

+27-17
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use borrow::Borrow;
1515
use cmp::max;
1616
use fmt::{self, Debug};
1717
use hash::{Hash, SipHasher, BuildHasher};
18-
use iter::{self, Map, FromIterator};
18+
use iter::FromIterator;
1919
use mem::{self, replace};
2020
use ops::{Deref, Index};
2121
use rand::{self, Rng};
@@ -836,8 +836,7 @@ impl<K, V, S> HashMap<K, V, S>
836836
/// ```
837837
#[stable(feature = "rust1", since = "1.0.0")]
838838
pub fn keys<'a>(&'a self) -> Keys<'a, K, V> {
839-
fn first<A, B>((a, _): (A, B)) -> A { a }
840-
Keys { inner: self.iter().map(first) }
839+
Keys { inner: self.iter() }
841840
}
842841

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

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

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

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

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

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

12681265
enum InternalEntry<K, V, M> {
@@ -1397,9 +1394,8 @@ impl<K, V, S> IntoIterator for HashMap<K, V, S>
13971394
/// let vec: Vec<(&str, isize)> = map.into_iter().collect();
13981395
/// ```
13991396
fn into_iter(self) -> IntoIter<K, V> {
1400-
fn last_two<A, B, C>((_, b, c): (A, B, C)) -> (B, C) { (b, c) }
14011397
IntoIter {
1402-
inner: self.table.into_iter().map(last_two)
1398+
inner: self.table.into_iter()
14031399
}
14041400
}
14051401
}
@@ -1432,7 +1428,7 @@ impl<'a, K, V> ExactSizeIterator for IterMut<'a, K, V> {
14321428
impl<K, V> Iterator for IntoIter<K, V> {
14331429
type Item = (K, V);
14341430

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

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

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

1471-
#[inline] fn next(&mut self) -> Option<(K, V)> { self.inner.next() }
1467+
#[inline] fn next(&mut self) -> Option<(K, V)> { self.inner.next().map(|(_, k, v)| (k, v)) }
14721468
#[inline] fn size_hint(&self) -> (usize, Option<usize>) { self.inner.size_hint() }
14731469
}
14741470
#[stable(feature = "rust1", since = "1.0.0")]
@@ -1674,6 +1670,20 @@ impl<K, S, Q: ?Sized> super::Recover<Q> for HashMap<K, (), S>
16741670
}
16751671
}
16761672

1673+
#[allow(dead_code)]
1674+
fn assert_covariance() {
1675+
fn map_key<'new>(v: HashMap<&'static str, u8>) -> HashMap<&'new str, u8> { v }
1676+
fn map_val<'new>(v: HashMap<u8, &'static str>) -> HashMap<u8, &'new str> { v }
1677+
fn iter_key<'a, 'new>(v: Iter<'a, &'static str, u8>) -> Iter<'a, &'new str, u8> { v }
1678+
fn iter_val<'a, 'new>(v: Iter<'a, u8, &'static str>) -> Iter<'a, u8, &'new str> { v }
1679+
fn into_iter_key<'new>(v: IntoIter<&'static str, u8>) -> IntoIter<&'new str, u8> { v }
1680+
fn into_iter_val<'new>(v: IntoIter<u8, &'static str>) -> IntoIter<u8, &'new str> { v }
1681+
fn keys_key<'a, 'new>(v: Keys<'a, &'static str, u8>) -> Keys<'a, &'new str, u8> { v }
1682+
fn keys_val<'a, 'new>(v: Keys<'a, u8, &'static str>) -> Keys<'a, u8, &'new str> { v }
1683+
fn values_key<'a, 'new>(v: Values<'a, &'static str, u8>) -> Values<'a, &'new str, u8> { v }
1684+
fn values_val<'a, 'new>(v: Values<'a, u8, &'static str>) -> Values<'a, u8, &'new str> { v }
1685+
}
1686+
16771687
#[cfg(test)]
16781688
mod test_map {
16791689
use prelude::v1::*;

src/libstd/collections/hash/set.rs

+22-9
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
use borrow::Borrow;
1212
use fmt;
1313
use hash::{Hash, BuildHasher};
14-
use iter::{Map, Chain, FromIterator};
14+
use iter::{Chain, FromIterator};
1515
use ops::{BitOr, BitAnd, BitXor, Sub};
1616

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

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

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

821820
/// Intersection iterator
@@ -889,8 +888,7 @@ impl<T, S> IntoIterator for HashSet<T, S>
889888
/// }
890889
/// ```
891890
fn into_iter(self) -> IntoIter<T> {
892-
fn first<A, B>((a, _): (A, B)) -> A { a }
893-
IntoIter { iter: self.map.into_iter().map(first) }
891+
IntoIter { iter: self.map.into_iter() }
894892
}
895893
}
896894

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

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

929-
fn next(&mut self) -> Option<K> { self.iter.next() }
927+
fn next(&mut self) -> Option<K> { self.iter.next().map(|(k, _)| k) }
930928
fn size_hint(&self) -> (usize, Option<usize>) { self.iter.size_hint() }
931929
}
932930
#[stable(feature = "rust1", since = "1.0.0")]
@@ -1026,6 +1024,21 @@ impl<'a, T, S> Iterator for Union<'a, T, S>
10261024
fn size_hint(&self) -> (usize, Option<usize>) { self.iter.size_hint() }
10271025
}
10281026

1027+
#[allow(dead_code)]
1028+
fn assert_covariance() {
1029+
fn set<'new>(v: HashSet<&'static str>) -> HashSet<&'new str> { v }
1030+
fn iter<'a, 'new>(v: Iter<'a, &'static str>) -> Iter<'a, &'new str> { v }
1031+
fn into_iter<'new>(v: IntoIter<&'static str>) -> IntoIter<&'new str> { v }
1032+
fn difference<'a, 'new>(v: Difference<'a, &'static str, RandomState>)
1033+
-> Difference<'a, &'new str, RandomState> { v }
1034+
fn symmetric_difference<'a, 'new>(v: SymmetricDifference<'a, &'static str, RandomState>)
1035+
-> SymmetricDifference<'a, &'new str, RandomState> { v }
1036+
fn intersection<'a, 'new>(v: Intersection<'a, &'static str, RandomState>)
1037+
-> Intersection<'a, &'new str, RandomState> { v }
1038+
fn union<'a, 'new>(v: Union<'a, &'static str, RandomState>)
1039+
-> Union<'a, &'new str, RandomState> { v }
1040+
}
1041+
10291042
#[cfg(test)]
10301043
mod test_set {
10311044
use prelude::v1::*;

src/libstd/collections/hash/table.rs

+23-18
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,10 @@ unsafe impl<K: Sync, V: Sync> Sync for RawTable<K, V> {}
7575

7676
struct RawBucket<K, V> {
7777
hash: *mut u64,
78-
key: *mut K,
79-
val: *mut V,
78+
79+
// We use *const to ensure covariance with respect to K and V
80+
key: *const K,
81+
val: *const V,
8082
_marker: marker::PhantomData<(K,V)>,
8183
}
8284

@@ -354,8 +356,8 @@ impl<K, V, M> EmptyBucket<K, V, M> where M: Put<K, V> {
354356
-> FullBucket<K, V, M> {
355357
unsafe {
356358
*self.raw.hash = hash.inspect();
357-
ptr::write(self.raw.key, key);
358-
ptr::write(self.raw.val, value);
359+
ptr::write(self.raw.key as *mut K, key);
360+
ptr::write(self.raw.val as *mut V, value);
359361

360362
self.table.borrow_table_mut().size += 1;
361363
}
@@ -453,8 +455,8 @@ impl<K, V, M> FullBucket<K, V, M> where M: Put<K, V> {
453455
pub fn replace(&mut self, h: SafeHash, k: K, v: V) -> (SafeHash, K, V) {
454456
unsafe {
455457
let old_hash = ptr::replace(self.raw.hash as *mut SafeHash, h);
456-
let old_key = ptr::replace(self.raw.key, k);
457-
let old_val = ptr::replace(self.raw.val, v);
458+
let old_key = ptr::replace(self.raw.key as *mut K, k);
459+
let old_val = ptr::replace(self.raw.val as *mut V, v);
458460

459461
(old_hash, old_key, old_val)
460462
}
@@ -465,8 +467,8 @@ impl<K, V, M> FullBucket<K, V, M> where M: Deref<Target=RawTable<K, V>> + DerefM
465467
/// Gets mutable references to the key and value at a given index.
466468
pub fn read_mut(&mut self) -> (&mut K, &mut V) {
467469
unsafe {
468-
(&mut *self.raw.key,
469-
&mut *self.raw.val)
470+
(&mut *(self.raw.key as *mut K),
471+
&mut *(self.raw.val as *mut V))
470472
}
471473
}
472474
}
@@ -490,8 +492,8 @@ impl<'t, K, V, M> FullBucket<K, V, M> where M: Deref<Target=RawTable<K, V>> + De
490492
/// for mutable references into the table.
491493
pub fn into_mut_refs(self) -> (&'t mut K, &'t mut V) {
492494
unsafe {
493-
(&mut *self.raw.key,
494-
&mut *self.raw.val)
495+
(&mut *(self.raw.key as *mut K),
496+
&mut *(self.raw.val as *mut V))
495497
}
496498
}
497499
}
@@ -505,8 +507,8 @@ impl<K, V, M> GapThenFull<K, V, M> where M: Deref<Target=RawTable<K, V>> {
505507
pub fn shift(mut self) -> Option<GapThenFull<K, V, M>> {
506508
unsafe {
507509
*self.gap.raw.hash = mem::replace(&mut *self.full.raw.hash, EMPTY_BUCKET);
508-
ptr::copy_nonoverlapping(self.full.raw.key, self.gap.raw.key, 1);
509-
ptr::copy_nonoverlapping(self.full.raw.val, self.gap.raw.val, 1);
510+
ptr::copy_nonoverlapping(self.full.raw.key, self.gap.raw.key as *mut K, 1);
511+
ptr::copy_nonoverlapping(self.full.raw.val, self.gap.raw.val as *mut V, 1);
510512
}
511513

512514
let FullBucket { raw: prev_raw, idx: prev_idx, .. } = self.full;
@@ -649,7 +651,7 @@ impl<K, V> RawTable<K, V> {
649651
let hashes_size = self.capacity * size_of::<u64>();
650652
let keys_size = self.capacity * size_of::<K>();
651653

652-
let buffer = *self.hashes as *mut u8;
654+
let buffer = *self.hashes as *const u8;
653655
let (keys_offset, vals_offset, oflo) =
654656
calculate_offsets(hashes_size,
655657
keys_size, align_of::<K>(),
@@ -658,8 +660,8 @@ impl<K, V> RawTable<K, V> {
658660
unsafe {
659661
RawBucket {
660662
hash: *self.hashes,
661-
key: buffer.offset(keys_offset as isize) as *mut K,
662-
val: buffer.offset(vals_offset as isize) as *mut V,
663+
key: buffer.offset(keys_offset as isize) as *const K,
664+
val: buffer.offset(vals_offset as isize) as *const V,
663665
_marker: marker::PhantomData,
664666
}
665667
}
@@ -707,6 +709,7 @@ impl<K, V> RawTable<K, V> {
707709
IterMut {
708710
iter: self.raw_buckets(),
709711
elems_left: self.size(),
712+
_marker: marker::PhantomData,
710713
}
711714
}
712715

@@ -858,6 +861,8 @@ impl<'a, K, V> Clone for Iter<'a, K, V> {
858861
pub struct IterMut<'a, K: 'a, V: 'a> {
859862
iter: RawBuckets<'a, K, V>,
860863
elems_left: usize,
864+
// To ensure invariance with respect to V
865+
_marker: marker::PhantomData<&'a mut V>,
861866
}
862867

863868
unsafe impl<'a, K: Sync, V: Sync> Sync for IterMut<'a, K, V> {}
@@ -912,7 +917,7 @@ impl<'a, K, V> Iterator for IterMut<'a, K, V> {
912917
self.elems_left -= 1;
913918
unsafe {
914919
(&*bucket.key,
915-
&mut *bucket.val)
920+
&mut *(bucket.val as *mut V))
916921
}
917922
})
918923
}
@@ -1003,8 +1008,8 @@ impl<K: Clone, V: Clone> Clone for RawTable<K, V> {
10031008
(full.hash(), k.clone(), v.clone())
10041009
};
10051010
*new_buckets.raw.hash = h.inspect();
1006-
ptr::write(new_buckets.raw.key, k);
1007-
ptr::write(new_buckets.raw.val, v);
1011+
ptr::write(new_buckets.raw.key as *mut K, k);
1012+
ptr::write(new_buckets.raw.val as *mut V, v);
10081013
}
10091014
Empty(..) => {
10101015
*new_buckets.raw.hash = EMPTY_BUCKET;

0 commit comments

Comments
 (0)