Skip to content

Commit 285a40a

Browse files
committed
Make HashMap's RawBucket covariant
1 parent 30a3849 commit 285a40a

File tree

1 file changed

+23
-18
lines changed

1 file changed

+23
-18
lines changed

src/libstd/collections/hash/table.rs

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,10 @@ unsafe impl<K: Sync, V: Sync> Sync for RawTable<K, V> {}
7575

7676
struct RawBucket<K, V> {
7777
hash: *mut u64,
78-
key: *mut K,
79-
val: *mut V,
78+
79+
// We use *const to ensure covariance with respect to K and V
80+
key: *const K,
81+
val: *const V,
8082
_marker: marker::PhantomData<(K,V)>,
8183
}
8284

@@ -354,8 +356,8 @@ impl<K, V, M> EmptyBucket<K, V, M> where M: Put<K, V> {
354356
-> FullBucket<K, V, M> {
355357
unsafe {
356358
*self.raw.hash = hash.inspect();
357-
ptr::write(self.raw.key, key);
358-
ptr::write(self.raw.val, value);
359+
ptr::write(self.raw.key as *mut K, key);
360+
ptr::write(self.raw.val as *mut V, value);
359361

360362
self.table.borrow_table_mut().size += 1;
361363
}
@@ -453,8 +455,8 @@ impl<K, V, M> FullBucket<K, V, M> where M: Put<K, V> {
453455
pub fn replace(&mut self, h: SafeHash, k: K, v: V) -> (SafeHash, K, V) {
454456
unsafe {
455457
let old_hash = ptr::replace(self.raw.hash as *mut SafeHash, h);
456-
let old_key = ptr::replace(self.raw.key, k);
457-
let old_val = ptr::replace(self.raw.val, v);
458+
let old_key = ptr::replace(self.raw.key as *mut K, k);
459+
let old_val = ptr::replace(self.raw.val as *mut V, v);
458460

459461
(old_hash, old_key, old_val)
460462
}
@@ -465,8 +467,8 @@ impl<K, V, M> FullBucket<K, V, M> where M: Deref<Target=RawTable<K, V>> + DerefM
465467
/// Gets mutable references to the key and value at a given index.
466468
pub fn read_mut(&mut self) -> (&mut K, &mut V) {
467469
unsafe {
468-
(&mut *self.raw.key,
469-
&mut *self.raw.val)
470+
(&mut *(self.raw.key as *mut K),
471+
&mut *(self.raw.val as *mut V))
470472
}
471473
}
472474
}
@@ -490,8 +492,8 @@ impl<'t, K, V, M> FullBucket<K, V, M> where M: Deref<Target=RawTable<K, V>> + De
490492
/// for mutable references into the table.
491493
pub fn into_mut_refs(self) -> (&'t mut K, &'t mut V) {
492494
unsafe {
493-
(&mut *self.raw.key,
494-
&mut *self.raw.val)
495+
(&mut *(self.raw.key as *mut K),
496+
&mut *(self.raw.val as *mut V))
495497
}
496498
}
497499
}
@@ -505,8 +507,8 @@ impl<K, V, M> GapThenFull<K, V, M> where M: Deref<Target=RawTable<K, V>> {
505507
pub fn shift(mut self) -> Option<GapThenFull<K, V, M>> {
506508
unsafe {
507509
*self.gap.raw.hash = mem::replace(&mut *self.full.raw.hash, EMPTY_BUCKET);
508-
ptr::copy_nonoverlapping(self.full.raw.key, self.gap.raw.key, 1);
509-
ptr::copy_nonoverlapping(self.full.raw.val, self.gap.raw.val, 1);
510+
ptr::copy_nonoverlapping(self.full.raw.key, self.gap.raw.key as *mut K, 1);
511+
ptr::copy_nonoverlapping(self.full.raw.val, self.gap.raw.val as *mut V, 1);
510512
}
511513

512514
let FullBucket { raw: prev_raw, idx: prev_idx, .. } = self.full;
@@ -649,7 +651,7 @@ impl<K, V> RawTable<K, V> {
649651
let hashes_size = self.capacity * size_of::<u64>();
650652
let keys_size = self.capacity * size_of::<K>();
651653

652-
let buffer = *self.hashes as *mut u8;
654+
let buffer = *self.hashes as *const u8;
653655
let (keys_offset, vals_offset, oflo) =
654656
calculate_offsets(hashes_size,
655657
keys_size, align_of::<K>(),
@@ -658,8 +660,8 @@ impl<K, V> RawTable<K, V> {
658660
unsafe {
659661
RawBucket {
660662
hash: *self.hashes,
661-
key: buffer.offset(keys_offset as isize) as *mut K,
662-
val: buffer.offset(vals_offset as isize) as *mut V,
663+
key: buffer.offset(keys_offset as isize) as *const K,
664+
val: buffer.offset(vals_offset as isize) as *const V,
663665
_marker: marker::PhantomData,
664666
}
665667
}
@@ -707,6 +709,7 @@ impl<K, V> RawTable<K, V> {
707709
IterMut {
708710
iter: self.raw_buckets(),
709711
elems_left: self.size(),
712+
_marker: marker::PhantomData,
710713
}
711714
}
712715

@@ -858,6 +861,8 @@ impl<'a, K, V> Clone for Iter<'a, K, V> {
858861
pub struct IterMut<'a, K: 'a, V: 'a> {
859862
iter: RawBuckets<'a, K, V>,
860863
elems_left: usize,
864+
// To ensure invariance with respect to V
865+
_marker: marker::PhantomData<&'a mut V>,
861866
}
862867

863868
unsafe impl<'a, K: Sync, V: Sync> Sync for IterMut<'a, K, V> {}
@@ -912,7 +917,7 @@ impl<'a, K, V> Iterator for IterMut<'a, K, V> {
912917
self.elems_left -= 1;
913918
unsafe {
914919
(&*bucket.key,
915-
&mut *bucket.val)
920+
&mut *(bucket.val as *mut V))
916921
}
917922
})
918923
}
@@ -1003,8 +1008,8 @@ impl<K: Clone, V: Clone> Clone for RawTable<K, V> {
10031008
(full.hash(), k.clone(), v.clone())
10041009
};
10051010
*new_buckets.raw.hash = h.inspect();
1006-
ptr::write(new_buckets.raw.key, k);
1007-
ptr::write(new_buckets.raw.val, v);
1011+
ptr::write(new_buckets.raw.key as *mut K, k);
1012+
ptr::write(new_buckets.raw.val as *mut V, v);
10081013
}
10091014
Empty(..) => {
10101015
*new_buckets.raw.hash = EMPTY_BUCKET;

0 commit comments

Comments
 (0)