Skip to content

Commit

Permalink
Made vec_deque::Drain, hash_map::Drain, and hash_set::Drain covariant
Browse files Browse the repository at this point in the history
  • Loading branch information
tomgarcia committed Aug 5, 2016
1 parent 40f3ee2 commit bf592ce
Show file tree
Hide file tree
Showing 5 changed files with 23 additions and 9 deletions.
7 changes: 4 additions & 3 deletions src/libcollections/vec_deque.rs
Expand Up @@ -24,6 +24,7 @@ use core::iter::{repeat, FromIterator};
use core::mem;
use core::ops::{Index, IndexMut};
use core::ptr;
use core::ptr::Shared;
use core::slice;

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

Drain {
deque: self as *mut _,
deque: unsafe { Shared::new(self as *mut _) },
after_tail: drain_head,
after_head: head,
iter: Iter {
Expand Down Expand Up @@ -1985,7 +1986,7 @@ pub struct Drain<'a, T: 'a> {
after_tail: usize,
after_head: usize,
iter: Iter<'a, T>,
deque: *mut VecDeque<T>,
deque: Shared<VecDeque<T>>,
}

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

let source_deque = unsafe { &mut *self.deque };
let source_deque = unsafe { &mut **self.deque };

// T = source_deque_tail; H = source_deque_head; t = drain_tail; h = drain_head
//
Expand Down
6 changes: 6 additions & 0 deletions src/libcollectionstest/vec_deque.rs
Expand Up @@ -10,6 +10,7 @@

use std::collections::VecDeque;
use std::fmt::Debug;
use std::collections::vec_deque::Drain;

use test;

Expand Down Expand Up @@ -999,3 +1000,8 @@ fn test_contains() {

assert!(!v.contains(&3));
}

#[allow(dead_code)]
fn assert_covariance() {
fn drain<'new>(d: Drain<'static, &'static str>) -> Drain<'new, &'new str> { d }
}
2 changes: 2 additions & 0 deletions src/libstd/collections/hash/map.rs
Expand Up @@ -2036,6 +2036,8 @@ fn assert_covariance() {
fn keys_val<'a, 'new>(v: Keys<'a, u8, &'static str>) -> Keys<'a, u8, &'new str> { v }
fn values_key<'a, 'new>(v: Values<'a, &'static str, u8>) -> Values<'a, &'new str, u8> { v }
fn values_val<'a, 'new>(v: Values<'a, u8, &'static str>) -> Values<'a, u8, &'new str> { v }
fn drain<'new>(d: Drain<'static, &'static str, &'static str>)
-> Drain<'new, &'new str, &'new str> { d }
}

#[cfg(test)]
Expand Down
1 change: 1 addition & 0 deletions src/libstd/collections/hash/set.rs
Expand Up @@ -1036,6 +1036,7 @@ fn assert_covariance() {
-> Intersection<'a, &'new str, RandomState> { v }
fn union<'a, 'new>(v: Union<'a, &'static str, RandomState>)
-> Union<'a, &'new str, RandomState> { v }
fn drain<'new>(d: Drain<'static, &'static str>) -> Drain<'new, &'new str> { d }
}

#[cfg(test)]
Expand Down
16 changes: 10 additions & 6 deletions src/libstd/collections/hash/table.rs
Expand Up @@ -17,7 +17,7 @@ use marker;
use mem::{align_of, size_of};
use mem;
use ops::{Deref, DerefMut};
use ptr::{self, Unique};
use ptr::{self, Unique, Shared};

use self::BucketState::*;

Expand Down Expand Up @@ -754,7 +754,8 @@ impl<K, V> RawTable<K, V> {
hashes_end: hashes_end,
marker: marker::PhantomData,
},
table: self,
table: unsafe { Shared::new(self) },
marker: marker::PhantomData,
}
}

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

/// Iterator over the entries in a table, clearing the table.
pub struct Drain<'a, K: 'a, V: 'a> {
table: &'a mut RawTable<K, V>,
table: Shared<RawTable<K, V>>,
iter: RawBuckets<'static, K, V>,
marker: marker::PhantomData<&'a RawTable<K, V>>,
}

unsafe impl<'a, K: Sync, V: Sync> Sync for Drain<'a, K, V> {}
Expand Down Expand Up @@ -973,8 +975,8 @@ impl<'a, K, V> Iterator for Drain<'a, K, V> {
#[inline]
fn next(&mut self) -> Option<(SafeHash, K, V)> {
self.iter.next().map(|bucket| {
self.table.size -= 1;
unsafe {
(**self.table).size -= 1;
(SafeHash { hash: ptr::replace(bucket.hash, EMPTY_BUCKET) },
ptr::read(bucket.key),
ptr::read(bucket.val))
Expand All @@ -983,13 +985,15 @@ impl<'a, K, V> Iterator for Drain<'a, K, V> {
}

fn size_hint(&self) -> (usize, Option<usize>) {
let size = self.table.size();
let size = unsafe { (**self.table).size() };
(size, Some(size))
}
}
impl<'a, K, V> ExactSizeIterator for Drain<'a, K, V> {
fn len(&self) -> usize {
self.table.size()
unsafe {
(**self.table).size()
}
}
}

Expand Down

0 comments on commit bf592ce

Please sign in to comment.