diff --git a/src/libstd/collections/hash/table.rs b/src/libstd/collections/hash/table.rs index 349462aebe31b..8a822057bbff7 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 { table: RawTable, iter: RawBuckets<'static, K, V> } +unsafe impl Sync for IntoIter {} +unsafe impl Send for IntoIter {} + /// Iterator over the entries in a table, clearing the table. pub struct Drain<'a, K: 'a, V: 'a> { table: &'a mut RawTable, 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 0ee04c4463b0f..cdfc4d32027bb 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::::new(), intersection(&BTreeSet::::new())); is_sync_send!(BTreeSet::::new(), union(&BTreeSet::::new())); + all_sync_send!(HashMap::::new(), iter, iter_mut, drain, into_iter, keys, values); + all_sync_send!(HashSet::::new(), iter, drain, into_iter); + is_sync_send!(HashSet::::new(), difference(&HashSet::::new())); + is_sync_send!(HashSet::::new(), symmetric_difference(&HashSet::::new())); + is_sync_send!(HashSet::::new(), intersection(&HashSet::::new())); + is_sync_send!(HashSet::::new(), union(&HashSet::::new())); + all_sync_send!(LinkedList::::new(), iter, iter_mut, into_iter); #[derive(Copy, Clone)]