Skip to content

Commit 514d4ce

Browse files
authored
Auto merge of #35354 - tomgarcia:covariant-drain, r=alexcrichton
Made vec_deque::Drain, hash_map::Drain, and hash_set::Drain covariant Fixed the rest of the Drain iterators.
2 parents db7300d + bf592ce commit 514d4ce

File tree

5 files changed

+23
-9
lines changed

5 files changed

+23
-9
lines changed

src/libcollections/vec_deque.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ use core::iter::{repeat, FromIterator};
2424
use core::mem;
2525
use core::ops::{Index, IndexMut};
2626
use core::ptr;
27+
use core::ptr::Shared;
2728
use core::slice;
2829

2930
use core::hash::{Hash, Hasher};
@@ -903,7 +904,7 @@ impl<T> VecDeque<T> {
903904
self.head = drain_tail;
904905

905906
Drain {
906-
deque: self as *mut _,
907+
deque: unsafe { Shared::new(self as *mut _) },
907908
after_tail: drain_head,
908909
after_head: head,
909910
iter: Iter {
@@ -1985,7 +1986,7 @@ pub struct Drain<'a, T: 'a> {
19851986
after_tail: usize,
19861987
after_head: usize,
19871988
iter: Iter<'a, T>,
1988-
deque: *mut VecDeque<T>,
1989+
deque: Shared<VecDeque<T>>,
19891990
}
19901991

19911992
#[stable(feature = "drain", since = "1.6.0")]
@@ -1998,7 +1999,7 @@ impl<'a, T: 'a> Drop for Drain<'a, T> {
19981999
fn drop(&mut self) {
19992000
for _ in self.by_ref() {}
20002001

2001-
let source_deque = unsafe { &mut *self.deque };
2002+
let source_deque = unsafe { &mut **self.deque };
20022003

20032004
// T = source_deque_tail; H = source_deque_head; t = drain_tail; h = drain_head
20042005
//

src/libcollectionstest/vec_deque.rs

+6
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
use std::collections::VecDeque;
1212
use std::fmt::Debug;
13+
use std::collections::vec_deque::Drain;
1314

1415
use test;
1516

@@ -999,3 +1000,8 @@ fn test_contains() {
9991000

10001001
assert!(!v.contains(&3));
10011002
}
1003+
1004+
#[allow(dead_code)]
1005+
fn assert_covariance() {
1006+
fn drain<'new>(d: Drain<'static, &'static str>) -> Drain<'new, &'new str> { d }
1007+
}

src/libstd/collections/hash/map.rs

+2
Original file line numberDiff line numberDiff line change
@@ -2035,6 +2035,8 @@ fn assert_covariance() {
20352035
fn keys_val<'a, 'new>(v: Keys<'a, u8, &'static str>) -> Keys<'a, u8, &'new str> { v }
20362036
fn values_key<'a, 'new>(v: Values<'a, &'static str, u8>) -> Values<'a, &'new str, u8> { v }
20372037
fn values_val<'a, 'new>(v: Values<'a, u8, &'static str>) -> Values<'a, u8, &'new str> { v }
2038+
fn drain<'new>(d: Drain<'static, &'static str, &'static str>)
2039+
-> Drain<'new, &'new str, &'new str> { d }
20382040
}
20392041

20402042
#[cfg(test)]

src/libstd/collections/hash/set.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1036,6 +1036,7 @@ fn assert_covariance() {
10361036
-> Intersection<'a, &'new str, RandomState> { v }
10371037
fn union<'a, 'new>(v: Union<'a, &'static str, RandomState>)
10381038
-> Union<'a, &'new str, RandomState> { v }
1039+
fn drain<'new>(d: Drain<'static, &'static str>) -> Drain<'new, &'new str> { d }
10391040
}
10401041

10411042
#[cfg(test)]

src/libstd/collections/hash/table.rs

+10-6
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use marker;
1717
use mem::{align_of, size_of};
1818
use mem;
1919
use ops::{Deref, DerefMut};
20-
use ptr::{self, Unique};
20+
use ptr::{self, Unique, Shared};
2121

2222
use self::BucketState::*;
2323

@@ -754,7 +754,8 @@ impl<K, V> RawTable<K, V> {
754754
hashes_end: hashes_end,
755755
marker: marker::PhantomData,
756756
},
757-
table: self,
757+
table: unsafe { Shared::new(self) },
758+
marker: marker::PhantomData,
758759
}
759760
}
760761

@@ -897,8 +898,9 @@ unsafe impl<K: Send, V: Send> Send for IntoIter<K, V> {}
897898

898899
/// Iterator over the entries in a table, clearing the table.
899900
pub struct Drain<'a, K: 'a, V: 'a> {
900-
table: &'a mut RawTable<K, V>,
901+
table: Shared<RawTable<K, V>>,
901902
iter: RawBuckets<'static, K, V>,
903+
marker: marker::PhantomData<&'a RawTable<K, V>>,
902904
}
903905

904906
unsafe impl<'a, K: Sync, V: Sync> Sync for Drain<'a, K, V> {}
@@ -973,8 +975,8 @@ impl<'a, K, V> Iterator for Drain<'a, K, V> {
973975
#[inline]
974976
fn next(&mut self) -> Option<(SafeHash, K, V)> {
975977
self.iter.next().map(|bucket| {
976-
self.table.size -= 1;
977978
unsafe {
979+
(**self.table).size -= 1;
978980
(SafeHash { hash: ptr::replace(bucket.hash, EMPTY_BUCKET) },
979981
ptr::read(bucket.key),
980982
ptr::read(bucket.val))
@@ -983,13 +985,15 @@ impl<'a, K, V> Iterator for Drain<'a, K, V> {
983985
}
984986

985987
fn size_hint(&self) -> (usize, Option<usize>) {
986-
let size = self.table.size();
988+
let size = unsafe { (**self.table).size() };
987989
(size, Some(size))
988990
}
989991
}
990992
impl<'a, K, V> ExactSizeIterator for Drain<'a, K, V> {
991993
fn len(&self) -> usize {
992-
self.table.size()
994+
unsafe {
995+
(**self.table).size()
996+
}
993997
}
994998
}
995999

0 commit comments

Comments
 (0)