]> git.lizzy.rs Git - rust.git/commitdiff
make Send/Sync impl of RawTable manual
authorAlexis <a.beingessner@gmail.com>
Fri, 30 Jan 2015 03:18:45 +0000 (22:18 -0500)
committerAlexis <a.beingessner@gmail.com>
Sat, 31 Jan 2015 19:11:53 +0000 (14:11 -0500)
src/libstd/collections/hash/table.rs
src/test/compile-fail/issue-21763.rs [new file with mode: 0644]

index 8016a343d67c5fe207ba925721a35ccd2252551c..8952b81690186545d3abae3318e0d75de7def7fa 100644 (file)
 use cmp;
 use hash::{Hash, Hasher};
 use iter::{Iterator, IteratorExt, ExactSizeIterator, count};
-use marker::{Copy, Sized, self};
+use marker::{Copy, Send, Sync, Sized, self};
 use mem::{min_align_of, size_of};
 use mem;
 use num::{Int, UnsignedInt};
 use ops::{Deref, DerefMut, Drop};
 use option::Option;
 use option::Option::{Some, None};
-use ptr::{Unique, PtrExt, copy_nonoverlapping_memory, zero_memory};
-use ptr;
+use ptr::{self, PtrExt, copy_nonoverlapping_memory, zero_memory};
 use rt::heap::{allocate, deallocate};
 use collections::hash_state::HashState;
 
 pub struct RawTable<K, V> {
     capacity: uint,
     size:     uint,
-    hashes:   Unique<u64>,
+    hashes:   *mut u64,
     // Because K/V do not appear directly in any of the types in the struct,
     // inform rustc that in fact instances of K and V are reachable from here.
     marker:   marker::CovariantType<(K,V)>,
 }
 
+unsafe impl<K: Send, V: Send> Send for RawTable<K, V> {}
+unsafe impl<K: Sync, V: Sync> Sync for RawTable<K, V> {}
+
 struct RawBucket<K, V> {
     hash: *mut u64,
     key:  *mut K,
@@ -565,7 +567,7 @@ unsafe fn new_uninitialized(capacity: uint) -> RawTable<K, V> {
             return RawTable {
                 size: 0,
                 capacity: 0,
-                hashes: Unique::null(),
+                hashes: ptr::null_mut(),
                 marker: marker::CovariantType,
             };
         }
@@ -604,7 +606,7 @@ unsafe fn new_uninitialized(capacity: uint) -> RawTable<K, V> {
         RawTable {
             capacity: capacity,
             size:     0,
-            hashes:   Unique(hashes),
+            hashes:   hashes,
             marker:   marker::CovariantType,
         }
     }
@@ -613,14 +615,14 @@ fn first_bucket_raw(&self) -> RawBucket<K, V> {
         let hashes_size = self.capacity * size_of::<u64>();
         let keys_size = self.capacity * size_of::<K>();
 
-        let buffer = self.hashes.0 as *mut u8;
+        let buffer = self.hashes as *mut u8;
         let (keys_offset, vals_offset) = calculate_offsets(hashes_size,
                                                            keys_size, min_align_of::<K>(),
                                                            min_align_of::<V>());
 
         unsafe {
             RawBucket {
-                hash: self.hashes.0,
+                hash: self.hashes,
                 key:  buffer.offset(keys_offset as int) as *mut K,
                 val:  buffer.offset(vals_offset as int) as *mut V
             }
@@ -632,7 +634,7 @@ fn first_bucket_raw(&self) -> RawBucket<K, V> {
     pub fn new(capacity: uint) -> RawTable<K, V> {
         unsafe {
             let ret = RawTable::new_uninitialized(capacity);
-            zero_memory(ret.hashes.0, capacity);
+            zero_memory(ret.hashes, capacity);
             ret
         }
     }
@@ -652,7 +654,7 @@ fn raw_buckets(&self) -> RawBuckets<K, V> {
         RawBuckets {
             raw: self.first_bucket_raw(),
             hashes_end: unsafe {
-                self.hashes.0.offset(self.capacity as int)
+                self.hashes.offset(self.capacity as int)
             },
             marker: marker::ContravariantLifetime,
         }
@@ -964,7 +966,7 @@ fn clone(&self) -> RawTable<K, V> {
 #[unsafe_destructor]
 impl<K, V> Drop for RawTable<K, V> {
     fn drop(&mut self) {
-        if self.hashes.0.is_null() {
+        if self.hashes.is_null() {
             return;
         }
         // This is done in reverse because we've likely partially taken
@@ -984,7 +986,7 @@ fn drop(&mut self) {
                                                     vals_size, min_align_of::<V>());
 
         unsafe {
-            deallocate(self.hashes.0 as *mut u8, size, align);
+            deallocate(self.hashes as *mut u8, size, align);
             // Remember how everything was allocated out of one buffer
             // during initialization? We only need one call to free here.
         }
diff --git a/src/test/compile-fail/issue-21763.rs b/src/test/compile-fail/issue-21763.rs
new file mode 100644 (file)
index 0000000..bcf3a0a
--- /dev/null
@@ -0,0 +1,21 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Regression test for HashMap only impl'ing Send/Sync if its contents do
+
+use std::collections::HashMap;
+use std::rc::Rc;
+
+fn foo<T: Send>() {}
+
+fn main() {
+    foo::<HashMap<Rc<()>, Rc<()>>>();
+    //~^ ERROR: the trait `core::marker::Send` is not implemented for the type `alloc::rc::Rc<()>`
+}