Skip to content

Commit a2aee62

Browse files
committed
Auto merge of #21768 - Gankro:hash-send, r=alexcrichton
Fixes #21763 (untested)
2 parents e8489d3 + 9985991 commit a2aee62

File tree

2 files changed

+35
-12
lines changed

2 files changed

+35
-12
lines changed

src/libstd/collections/hash/table.rs

+14-12
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,14 @@ use clone::Clone;
1616
use cmp;
1717
use hash::{Hash, Hasher};
1818
use iter::{Iterator, IteratorExt, ExactSizeIterator, count};
19-
use marker::{Copy, Sized, self};
19+
use marker::{Copy, Send, Sync, Sized, self};
2020
use mem::{min_align_of, size_of};
2121
use mem;
2222
use num::{Int, UnsignedInt};
2323
use ops::{Deref, DerefMut, Drop};
2424
use option::Option;
2525
use option::Option::{Some, None};
26-
use ptr::{Unique, PtrExt, copy_nonoverlapping_memory, zero_memory};
27-
use ptr;
26+
use ptr::{self, PtrExt, copy_nonoverlapping_memory, zero_memory};
2827
use rt::heap::{allocate, deallocate};
2928
use collections::hash_state::HashState;
3029

@@ -70,12 +69,15 @@ const EMPTY_BUCKET: u64 = 0u64;
7069
pub struct RawTable<K, V> {
7170
capacity: uint,
7271
size: uint,
73-
hashes: Unique<u64>,
72+
hashes: *mut u64,
7473
// Because K/V do not appear directly in any of the types in the struct,
7574
// inform rustc that in fact instances of K and V are reachable from here.
7675
marker: marker::CovariantType<(K,V)>,
7776
}
7877

78+
unsafe impl<K: Send, V: Send> Send for RawTable<K, V> {}
79+
unsafe impl<K: Sync, V: Sync> Sync for RawTable<K, V> {}
80+
7981
struct RawBucket<K, V> {
8082
hash: *mut u64,
8183
key: *mut K,
@@ -565,7 +567,7 @@ impl<K, V> RawTable<K, V> {
565567
return RawTable {
566568
size: 0,
567569
capacity: 0,
568-
hashes: Unique::null(),
570+
hashes: ptr::null_mut(),
569571
marker: marker::CovariantType,
570572
};
571573
}
@@ -604,7 +606,7 @@ impl<K, V> RawTable<K, V> {
604606
RawTable {
605607
capacity: capacity,
606608
size: 0,
607-
hashes: Unique(hashes),
609+
hashes: hashes,
608610
marker: marker::CovariantType,
609611
}
610612
}
@@ -613,14 +615,14 @@ impl<K, V> RawTable<K, V> {
613615
let hashes_size = self.capacity * size_of::<u64>();
614616
let keys_size = self.capacity * size_of::<K>();
615617

616-
let buffer = self.hashes.0 as *mut u8;
618+
let buffer = self.hashes as *mut u8;
617619
let (keys_offset, vals_offset) = calculate_offsets(hashes_size,
618620
keys_size, min_align_of::<K>(),
619621
min_align_of::<V>());
620622

621623
unsafe {
622624
RawBucket {
623-
hash: self.hashes.0,
625+
hash: self.hashes,
624626
key: buffer.offset(keys_offset as int) as *mut K,
625627
val: buffer.offset(vals_offset as int) as *mut V
626628
}
@@ -632,7 +634,7 @@ impl<K, V> RawTable<K, V> {
632634
pub fn new(capacity: uint) -> RawTable<K, V> {
633635
unsafe {
634636
let ret = RawTable::new_uninitialized(capacity);
635-
zero_memory(ret.hashes.0, capacity);
637+
zero_memory(ret.hashes, capacity);
636638
ret
637639
}
638640
}
@@ -652,7 +654,7 @@ impl<K, V> RawTable<K, V> {
652654
RawBuckets {
653655
raw: self.first_bucket_raw(),
654656
hashes_end: unsafe {
655-
self.hashes.0.offset(self.capacity as int)
657+
self.hashes.offset(self.capacity as int)
656658
},
657659
marker: marker::ContravariantLifetime,
658660
}
@@ -964,7 +966,7 @@ impl<K: Clone, V: Clone> Clone for RawTable<K, V> {
964966
#[unsafe_destructor]
965967
impl<K, V> Drop for RawTable<K, V> {
966968
fn drop(&mut self) {
967-
if self.hashes.0.is_null() {
969+
if self.hashes.is_null() {
968970
return;
969971
}
970972
// This is done in reverse because we've likely partially taken
@@ -984,7 +986,7 @@ impl<K, V> Drop for RawTable<K, V> {
984986
vals_size, min_align_of::<V>());
985987

986988
unsafe {
987-
deallocate(self.hashes.0 as *mut u8, size, align);
989+
deallocate(self.hashes as *mut u8, size, align);
988990
// Remember how everything was allocated out of one buffer
989991
// during initialization? We only need one call to free here.
990992
}

src/test/compile-fail/issue-21763.rs

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// Regression test for HashMap only impl'ing Send/Sync if its contents do
12+
13+
use std::collections::HashMap;
14+
use std::rc::Rc;
15+
16+
fn foo<T: Send>() {}
17+
18+
fn main() {
19+
foo::<HashMap<Rc<()>, Rc<()>>>();
20+
//~^ ERROR: the trait `core::marker::Send` is not implemented for the type `alloc::rc::Rc<()>`
21+
}

0 commit comments

Comments
 (0)