From 998599187fa0d1341ffd051e8d54b7ba7fea0be5 Mon Sep 17 00:00:00 2001 From: Alexis Date: Thu, 29 Jan 2015 22:18:45 -0500 Subject: [PATCH] make Send/Sync impl of RawTable manual --- src/libstd/collections/hash/table.rs | 26 ++++++++++++++------------ src/test/compile-fail/issue-21763.rs | 21 +++++++++++++++++++++ 2 files changed, 35 insertions(+), 12 deletions(-) create mode 100644 src/test/compile-fail/issue-21763.rs 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 { capacity: uint, size: uint, - hashes: Unique, + 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 Send for RawTable {} +unsafe impl Sync for RawTable {} + struct RawBucket { hash: *mut u64, key: *mut K, @@ -565,7 +567,7 @@ impl RawTable { return RawTable { size: 0, capacity: 0, - hashes: Unique::null(), + hashes: ptr::null_mut(), marker: marker::CovariantType, }; } @@ -604,7 +606,7 @@ impl RawTable { RawTable { capacity: capacity, size: 0, - hashes: Unique(hashes), + hashes: hashes, marker: marker::CovariantType, } } @@ -613,14 +615,14 @@ impl RawTable { let hashes_size = self.capacity * size_of::(); let keys_size = self.capacity * size_of::(); - 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::(), min_align_of::()); 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 RawTable { pub fn new(capacity: uint) -> RawTable { unsafe { let ret = RawTable::new_uninitialized(capacity); - zero_memory(ret.hashes.0, capacity); + zero_memory(ret.hashes, capacity); ret } } @@ -652,7 +654,7 @@ impl RawTable { 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 Clone for RawTable { #[unsafe_destructor] impl Drop for RawTable { 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 Drop for RawTable { vals_size, min_align_of::()); 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 or the MIT license +// , 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() {} + +fn main() { + foo::, Rc<()>>>(); + //~^ ERROR: the trait `core::marker::Send` is not implemented for the type `alloc::rc::Rc<()>` +}