diff options
| author | Alexis <a.beingessner@gmail.com> | 2015-01-29 22:18:45 -0500 |
|---|---|---|
| committer | Alexis <a.beingessner@gmail.com> | 2015-01-31 14:11:53 -0500 |
| commit | 998599187fa0d1341ffd051e8d54b7ba7fea0be5 (patch) | |
| tree | 9f7a5120f2d77898c7f77896b36395349adbb372 | |
| parent | 474b324eda10440d6568ef872a7307d38e7de95b (diff) | |
| download | rust-998599187fa0d1341ffd051e8d54b7ba7fea0be5.tar.gz rust-998599187fa0d1341ffd051e8d54b7ba7fea0be5.zip | |
make Send/Sync impl of RawTable manual
| -rw-r--r-- | src/libstd/collections/hash/table.rs | 26 | ||||
| -rw-r--r-- | src/test/compile-fail/issue-21763.rs | 21 |
2 files changed, 35 insertions, 12 deletions
diff --git a/src/libstd/collections/hash/table.rs b/src/libstd/collections/hash/table.rs index 8016a343d67..8952b816901 100644 --- a/src/libstd/collections/hash/table.rs +++ b/src/libstd/collections/hash/table.rs @@ -16,15 +16,14 @@ use clone::Clone; 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; @@ -70,12 +69,15 @@ const EMPTY_BUCKET: u64 = 0u64; 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 @@ impl<K, V> RawTable<K, V> { return RawTable { size: 0, capacity: 0, - hashes: Unique::null(), + hashes: ptr::null_mut(), marker: marker::CovariantType, }; } @@ -604,7 +606,7 @@ impl<K, V> RawTable<K, V> { RawTable { capacity: capacity, size: 0, - hashes: Unique(hashes), + hashes: hashes, marker: marker::CovariantType, } } @@ -613,14 +615,14 @@ impl<K, V> RawTable<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 @@ impl<K, V> RawTable<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 @@ impl<K, V> RawTable<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 @@ impl<K: Clone, V: Clone> Clone for 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 @@ impl<K, V> Drop for RawTable<K, V> { 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 index 00000000000..bcf3a0a9ac6 --- /dev/null +++ b/src/test/compile-fail/issue-21763.rs @@ -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<()>` +} |
