about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2015-08-12 03:11:48 +0000
committerbors <bors@rust-lang.org>2015-08-12 03:11:48 +0000
commit542d56ea91f403c5d7eb9511848509e5ddb8e05e (patch)
tree9c381964f45cd941dc48d642e0e1af240638cff2
parent58b0aa5e420643d454cf141263652a8bcb6a35f1 (diff)
parentf2f4a5c8621811c81d98f567e2505017aea94bce (diff)
downloadrust-542d56ea91f403c5d7eb9511848509e5ddb8e05e.tar.gz
rust-542d56ea91f403c5d7eb9511848509e5ddb8e05e.zip
Auto merge of #27615 - GuillaumeGomez:send_sync, r=huonw
Part of #22709.
cc @Veedrac

r? @bluss 
-rw-r--r--src/libstd/collections/hash/table.rs14
-rw-r--r--src/test/run-pass/sync-send-iterators-in-libcollections.rs9
2 files changed, 23 insertions, 0 deletions
diff --git a/src/libstd/collections/hash/table.rs b/src/libstd/collections/hash/table.rs
index 349462aebe3..8a822057bbf 100644
--- a/src/libstd/collections/hash/table.rs
+++ b/src/libstd/collections/hash/table.rs
@@ -818,6 +818,9 @@ pub struct Iter<'a, K: 'a, V: 'a> {
     elems_left: usize,
 }
 
+unsafe impl<'a, K: Sync, V: Sync> Sync for Iter<'a, K, V> {}
+unsafe impl<'a, K: Sync, V: Sync> Send for Iter<'a, K, V> {}
+
 // FIXME(#19839) Remove in favor of `#[derive(Clone)]`
 impl<'a, K, V> Clone for Iter<'a, K, V> {
     fn clone(&self) -> Iter<'a, K, V> {
@@ -835,18 +838,29 @@ pub struct IterMut<'a, K: 'a, V: 'a> {
     elems_left: usize,
 }
 
+unsafe impl<'a, K: Sync, V: Sync> Sync for IterMut<'a, K, V> {}
+// Both K: Sync and K: Send are correct for IterMut's Send impl,
+// but Send is the more useful bound
+unsafe impl<'a, K: Send, V: Send> Send for IterMut<'a, K, V> {}
+
 /// Iterator over the entries in a table, consuming the table.
 pub struct IntoIter<K, V> {
     table: RawTable<K, V>,
     iter: RawBuckets<'static, K, V>
 }
 
+unsafe impl<K: Sync, V: Sync> Sync for IntoIter<K, V> {}
+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>,
     iter: RawBuckets<'static, K, V>,
 }
 
+unsafe impl<'a, K: Sync, V: Sync> Sync for Drain<'a, K, V> {}
+unsafe impl<'a, K: Send, V: Send> Send for Drain<'a, K, V> {}
+
 impl<'a, K, V> Iterator for Iter<'a, K, V> {
     type Item = (&'a K, &'a V);
 
diff --git a/src/test/run-pass/sync-send-iterators-in-libcollections.rs b/src/test/run-pass/sync-send-iterators-in-libcollections.rs
index 0ee04c4463b..cdfc4d32027 100644
--- a/src/test/run-pass/sync-send-iterators-in-libcollections.rs
+++ b/src/test/run-pass/sync-send-iterators-in-libcollections.rs
@@ -25,6 +25,8 @@ use collections::String;
 use collections::Vec;
 use collections::VecDeque;
 use collections::VecMap;
+use std::collections::HashMap;
+use std::collections::HashSet;
 
 use collections::Bound::Included;
 use collections::enum_set::CLike;
@@ -77,6 +79,13 @@ fn main() {
     is_sync_send!(BTreeSet::<usize>::new(), intersection(&BTreeSet::<usize>::new()));
     is_sync_send!(BTreeSet::<usize>::new(), union(&BTreeSet::<usize>::new()));
 
+    all_sync_send!(HashMap::<usize, usize>::new(), iter, iter_mut, drain, into_iter, keys, values);
+    all_sync_send!(HashSet::<usize>::new(), iter, drain, into_iter);
+    is_sync_send!(HashSet::<usize>::new(), difference(&HashSet::<usize>::new()));
+    is_sync_send!(HashSet::<usize>::new(), symmetric_difference(&HashSet::<usize>::new()));
+    is_sync_send!(HashSet::<usize>::new(), intersection(&HashSet::<usize>::new()));
+    is_sync_send!(HashSet::<usize>::new(), union(&HashSet::<usize>::new()));
+
     all_sync_send!(LinkedList::<usize>::new(), iter, iter_mut, into_iter);
 
     #[derive(Copy, Clone)]