aboutsummaryrefslogtreecommitdiff
path: root/ctr-std/src/collections
diff options
context:
space:
mode:
authorFenrir <[email protected]>2017-12-01 21:57:34 -0700
committerFenrirWolf <[email protected]>2017-12-01 22:33:03 -0700
commit8ba058552b61484248fc295dfbbe2e18a9d49e48 (patch)
tree0c1bdd596147abee8dda56ac98ca009fa699a707 /ctr-std/src/collections
parentUpdate bindings for libctru v1.4.0 (diff)
downloadctru-rs-8ba058552b61484248fc295dfbbe2e18a9d49e48.tar.xz
ctru-rs-8ba058552b61484248fc295dfbbe2e18a9d49e48.zip
Patch `std` to be compatible with Rust nightly-2017-12-01
This only fixes things enough so that the project compiles again. More standard library changes from upstream Rust will be pulled in later.
Diffstat (limited to 'ctr-std/src/collections')
-rw-r--r--ctr-std/src/collections/hash/map.rs175
-rw-r--r--ctr-std/src/collections/hash/set.rs64
-rw-r--r--ctr-std/src/collections/hash/table.rs52
3 files changed, 231 insertions, 60 deletions
diff --git a/ctr-std/src/collections/hash/map.rs b/ctr-std/src/collections/hash/map.rs
index 746e180..7a79a47 100644
--- a/ctr-std/src/collections/hash/map.rs
+++ b/ctr-std/src/collections/hash/map.rs
@@ -20,8 +20,8 @@ use hash::{Hash, Hasher, BuildHasher, SipHasher13};
use iter::{FromIterator, FusedIterator};
use mem::{self, replace};
use ops::{Deref, Index, InPlace, Place, Placer};
-use rand::{self, Rng};
use ptr;
+use sys;
use super::table::{self, Bucket, EmptyBucket, FullBucket, FullBucketMut, RawTable, SafeHash};
use super::table::BucketState::{Empty, Full};
@@ -203,7 +203,7 @@ const DISPLACEMENT_THRESHOLD: usize = 128;
// so we round that up to 128.
//
// At a load factor of α, the odds of finding the target bucket after exactly n
-// unsuccesful probes[1] are
+// unsuccessful probes[1] are
//
// Pr_α{displacement = n} =
// (1 - α) / α * ∑_{k≥1} e^(-kα) * (kα)^(k+n) / (k + n)! * (1 - kα / (k + n + 1))
@@ -419,7 +419,7 @@ fn search_hashed<K, V, M, F>(table: M, hash: SafeHash, mut is_match: F) -> Inter
Empty(bucket) => {
// Found a hole!
return InternalEntry::Vacant {
- hash: hash,
+ hash,
elem: NoElem(bucket, displacement),
};
}
@@ -433,7 +433,7 @@ fn search_hashed<K, V, M, F>(table: M, hash: SafeHash, mut is_match: F) -> Inter
// We can finish the search early if we hit any bucket
// with a lower distance to initial bucket than we've probed.
return InternalEntry::Vacant {
- hash: hash,
+ hash,
elem: NeqElem(full, probe_displacement),
};
}
@@ -588,6 +588,9 @@ impl<K, V, S> HashMap<K, V, S>
impl<K: Hash + Eq, V> HashMap<K, V, RandomState> {
/// Creates an empty `HashMap`.
///
+ /// The hash map is initially created with a capacity of 0, so it will not allocate until it
+ /// is first inserted into.
+ ///
/// # Examples
///
/// ```
@@ -646,7 +649,7 @@ impl<K, V, S> HashMap<K, V, S>
#[stable(feature = "hashmap_build_hasher", since = "1.7.0")]
pub fn with_hasher(hash_builder: S) -> HashMap<K, V, S> {
HashMap {
- hash_builder: hash_builder,
+ hash_builder,
resize_policy: DefaultResizePolicy::new(),
table: RawTable::new(0),
}
@@ -679,8 +682,8 @@ impl<K, V, S> HashMap<K, V, S>
let resize_policy = DefaultResizePolicy::new();
let raw_cap = resize_policy.raw_capacity(capacity);
HashMap {
- hash_builder: hash_builder,
- resize_policy: resize_policy,
+ hash_builder,
+ resize_policy,
table: RawTable::new(raw_cap),
}
}
@@ -688,6 +691,17 @@ impl<K, V, S> HashMap<K, V, S>
/// Returns a reference to the map's [`BuildHasher`].
///
/// [`BuildHasher`]: ../../std/hash/trait.BuildHasher.html
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::collections::HashMap;
+ /// use std::collections::hash_map::RandomState;
+ ///
+ /// let hasher = RandomState::new();
+ /// let map: HashMap<isize, isize> = HashMap::with_hasher(hasher);
+ /// let hasher: &RandomState = map.hasher();
+ /// ```
#[stable(feature = "hashmap_public_hasher", since = "1.9.0")]
pub fn hasher(&self) -> &S {
&self.hash_builder
@@ -1099,6 +1113,7 @@ impl<K, V, S> HashMap<K, V, S>
/// assert_eq!(map.get(&2), None);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
+ #[inline]
pub fn get<Q: ?Sized>(&self, k: &Q) -> Option<&V>
where K: Borrow<Q>,
Q: Hash + Eq
@@ -1347,7 +1362,7 @@ pub struct Iter<'a, K: 'a, V: 'a> {
inner: table::Iter<'a, K, V>,
}
-// FIXME(#19839) Remove in favor of `#[derive(Clone)]`
+// FIXME(#26925) Remove in favor of `#[derive(Clone)]`
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, K, V> Clone for Iter<'a, K, V> {
fn clone(&self) -> Iter<'a, K, V> {
@@ -1400,7 +1415,7 @@ pub struct Keys<'a, K: 'a, V: 'a> {
inner: Iter<'a, K, V>,
}
-// FIXME(#19839) Remove in favor of `#[derive(Clone)]`
+// FIXME(#26925) Remove in favor of `#[derive(Clone)]`
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, K, V> Clone for Keys<'a, K, V> {
fn clone(&self) -> Keys<'a, K, V> {
@@ -1429,7 +1444,7 @@ pub struct Values<'a, K: 'a, V: 'a> {
inner: Iter<'a, K, V>,
}
-// FIXME(#19839) Remove in favor of `#[derive(Clone)]`
+// FIXME(#26925) Remove in favor of `#[derive(Clone)]`
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, K, V> Clone for Values<'a, K, V> {
fn clone(&self) -> Values<'a, K, V> {
@@ -1496,14 +1511,14 @@ impl<'a, K, V> InternalEntry<K, V, &'a mut RawTable<K, V>> {
InternalEntry::Occupied { elem } => {
Some(Occupied(OccupiedEntry {
key: Some(key),
- elem: elem,
+ elem,
}))
}
InternalEntry::Vacant { hash, elem } => {
Some(Vacant(VacantEntry {
- hash: hash,
- key: key,
- elem: elem,
+ hash,
+ key,
+ elem,
}))
}
InternalEntry::TableIsEmpty => None,
@@ -1618,7 +1633,7 @@ impl<'a, K, V, S> IntoIterator for &'a mut HashMap<K, V, S>
type Item = (&'a K, &'a mut V);
type IntoIter = IterMut<'a, K, V>;
- fn into_iter(mut self) -> IterMut<'a, K, V> {
+ fn into_iter(self) -> IterMut<'a, K, V> {
self.iter_mut()
}
}
@@ -1999,6 +2014,68 @@ impl<'a, K, V> Entry<'a, K, V> {
Vacant(ref entry) => entry.key(),
}
}
+
+ /// Provides in-place mutable access to an occupied entry before any
+ /// potential inserts into the map.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(entry_and_modify)]
+ /// use std::collections::HashMap;
+ ///
+ /// let mut map: HashMap<&str, u32> = HashMap::new();
+ ///
+ /// map.entry("poneyland")
+ /// .and_modify(|e| { *e += 1 })
+ /// .or_insert(42);
+ /// assert_eq!(map["poneyland"], 42);
+ ///
+ /// map.entry("poneyland")
+ /// .and_modify(|e| { *e += 1 })
+ /// .or_insert(42);
+ /// assert_eq!(map["poneyland"], 43);
+ /// ```
+ #[unstable(feature = "entry_and_modify", issue = "44733")]
+ pub fn and_modify<F>(self, mut f: F) -> Self
+ where F: FnMut(&mut V)
+ {
+ match self {
+ Occupied(mut entry) => {
+ f(entry.get_mut());
+ Occupied(entry)
+ },
+ Vacant(entry) => Vacant(entry),
+ }
+ }
+
+}
+
+impl<'a, K, V: Default> Entry<'a, K, V> {
+ #[unstable(feature = "entry_or_default", issue = "44324")]
+ /// Ensures a value is in the entry by inserting the default value if empty,
+ /// and returns a mutable reference to the value in the entry.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(entry_or_default)]
+ /// # fn main() {
+ /// use std::collections::HashMap;
+ ///
+ /// let mut map: HashMap<&str, Option<u32>> = HashMap::new();
+ /// map.entry("poneyland").or_default();
+ ///
+ /// assert_eq!(map["poneyland"], None);
+ /// # }
+ /// ```
+ pub fn or_default(self) -> &'a mut V {
+ match self {
+ Occupied(entry) => entry.into_mut(),
+ Vacant(entry) => entry.insert(Default::default()),
+ }
+ }
+
}
impl<'a, K, V> OccupiedEntry<'a, K, V> {
@@ -2161,6 +2238,68 @@ impl<'a, K, V> OccupiedEntry<'a, K, V> {
fn take_key(&mut self) -> Option<K> {
self.key.take()
}
+
+ /// Replaces the entry, returning the old key and value. The new key in the hash map will be
+ /// the key used to create this entry.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(map_entry_replace)]
+ /// use std::collections::hash_map::{Entry, HashMap};
+ /// use std::rc::Rc;
+ ///
+ /// let mut map: HashMap<Rc<String>, u32> = HashMap::new();
+ /// map.insert(Rc::new("Stringthing".to_string()), 15);
+ ///
+ /// let my_key = Rc::new("Stringthing".to_string());
+ ///
+ /// if let Entry::Occupied(entry) = map.entry(my_key) {
+ /// // Also replace the key with a handle to our other key.
+ /// let (old_key, old_value): (Rc<String>, u32) = entry.replace_entry(16);
+ /// }
+ ///
+ /// ```
+ #[unstable(feature = "map_entry_replace", issue = "44286")]
+ pub fn replace_entry(mut self, value: V) -> (K, V) {
+ let (old_key, old_value) = self.elem.read_mut();
+
+ let old_key = mem::replace(old_key, self.key.unwrap());
+ let old_value = mem::replace(old_value, value);
+
+ (old_key, old_value)
+ }
+
+ /// Replaces the key in the hash map with the key used to create this entry.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// #![feature(map_entry_replace)]
+ /// use std::collections::hash_map::{Entry, HashMap};
+ /// use std::rc::Rc;
+ ///
+ /// let mut map: HashMap<Rc<String>, u32> = HashMap::new();
+ /// let mut known_strings: Vec<Rc<String>> = Vec::new();
+ ///
+ /// // Initialise known strings, run program, etc.
+ ///
+ /// reclaim_memory(&mut map, &known_strings);
+ ///
+ /// fn reclaim_memory(map: &mut HashMap<Rc<String>, u32>, known_strings: &[Rc<String>] ) {
+ /// for s in known_strings {
+ /// if let Entry::Occupied(entry) = map.entry(s.clone()) {
+ /// // Replaces the entry's key with our version of it in `known_strings`.
+ /// entry.replace_key();
+ /// }
+ /// }
+ /// }
+ /// ```
+ #[unstable(feature = "map_entry_replace", issue = "44286")]
+ pub fn replace_key(mut self) -> K {
+ let (old_key, _) = self.elem.read_mut();
+ mem::replace(old_key, self.key.unwrap())
+ }
}
impl<'a, K: 'a, V: 'a> VacantEntry<'a, K, V> {
@@ -2354,9 +2493,7 @@ impl RandomState {
// increment one of the seeds on every RandomState creation, giving
// every corresponding HashMap a different iteration order.
thread_local!(static KEYS: Cell<(u64, u64)> = {
- let r = rand::OsRng::new();
- let mut r = r.expect("failed to create an OS RNG");
- Cell::new((r.gen(), r.gen()))
+ Cell::new(sys::hashmap_random_keys())
});
KEYS.with(|keys| {
@@ -2448,6 +2585,7 @@ impl<K, S, Q: ?Sized> super::Recover<Q> for HashMap<K, (), S>
{
type Key = K;
+ #[inline]
fn get(&self, key: &Q) -> Option<&K> {
self.search(key).into_occupied_bucket().map(|bucket| bucket.into_refs().0)
}
@@ -2460,6 +2598,7 @@ impl<K, S, Q: ?Sized> super::Recover<Q> for HashMap<K, (), S>
self.search_mut(key).into_occupied_bucket().map(|bucket| pop_internal(bucket).0)
}
+ #[inline]
fn replace(&mut self, key: K) -> Option<K> {
self.reserve(1);
diff --git a/ctr-std/src/collections/hash/set.rs b/ctr-std/src/collections/hash/set.rs
index d80df5f..51698ce 100644
--- a/ctr-std/src/collections/hash/set.rs
+++ b/ctr-std/src/collections/hash/set.rs
@@ -123,13 +123,16 @@ pub struct HashSet<T, S = RandomState> {
}
impl<T: Hash + Eq> HashSet<T, RandomState> {
- /// Creates an empty HashSet.
+ /// Creates an empty `HashSet`.
+ ///
+ /// The hash set is initially created with a capacity of 0, so it will not allocate until it
+ /// is first inserted into.
///
/// # Examples
///
/// ```
/// use std::collections::HashSet;
- /// let mut set: HashSet<i32> = HashSet::new();
+ /// let set: HashSet<i32> = HashSet::new();
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
@@ -146,7 +149,8 @@ impl<T: Hash + Eq> HashSet<T, RandomState> {
///
/// ```
/// use std::collections::HashSet;
- /// let mut set: HashSet<i32> = HashSet::with_capacity(10);
+ /// let set: HashSet<i32> = HashSet::with_capacity(10);
+ /// assert!(set.capacity() >= 10);
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
@@ -215,6 +219,17 @@ impl<T, S> HashSet<T, S>
/// Returns a reference to the set's [`BuildHasher`].
///
/// [`BuildHasher`]: ../../std/hash/trait.BuildHasher.html
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::collections::HashSet;
+ /// use std::collections::hash_map::RandomState;
+ ///
+ /// let hasher = RandomState::new();
+ /// let set: HashSet<i32> = HashSet::with_hasher(hasher);
+ /// let hasher: &RandomState = set.hasher();
+ /// ```
#[stable(feature = "hashmap_public_hasher", since = "1.9.0")]
pub fn hasher(&self) -> &S {
self.map.hasher()
@@ -249,6 +264,7 @@ impl<T, S> HashSet<T, S>
/// use std::collections::HashSet;
/// let mut set: HashSet<i32> = HashSet::new();
/// set.reserve(10);
+ /// assert!(set.capacity() >= 10);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn reserve(&mut self, additional: usize) {
@@ -312,19 +328,19 @@ impl<T, S> HashSet<T, S>
/// println!("{}", x); // Print 1
/// }
///
- /// let diff: HashSet<_> = a.difference(&b).cloned().collect();
- /// assert_eq!(diff, [1].iter().cloned().collect());
+ /// let diff: HashSet<_> = a.difference(&b).collect();
+ /// assert_eq!(diff, [1].iter().collect());
///
/// // Note that difference is not symmetric,
/// // and `b - a` means something else:
- /// let diff: HashSet<_> = b.difference(&a).cloned().collect();
- /// assert_eq!(diff, [4].iter().cloned().collect());
+ /// let diff: HashSet<_> = b.difference(&a).collect();
+ /// assert_eq!(diff, [4].iter().collect());
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn difference<'a>(&'a self, other: &'a HashSet<T, S>) -> Difference<'a, T, S> {
Difference {
iter: self.iter(),
- other: other,
+ other,
}
}
@@ -343,11 +359,11 @@ impl<T, S> HashSet<T, S>
/// println!("{}", x);
/// }
///
- /// let diff1: HashSet<_> = a.symmetric_difference(&b).cloned().collect();
- /// let diff2: HashSet<_> = b.symmetric_difference(&a).cloned().collect();
+ /// let diff1: HashSet<_> = a.symmetric_difference(&b).collect();
+ /// let diff2: HashSet<_> = b.symmetric_difference(&a).collect();
///
/// assert_eq!(diff1, diff2);
- /// assert_eq!(diff1, [1, 4].iter().cloned().collect());
+ /// assert_eq!(diff1, [1, 4].iter().collect());
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn symmetric_difference<'a>(&'a self,
@@ -371,14 +387,14 @@ impl<T, S> HashSet<T, S>
/// println!("{}", x);
/// }
///
- /// let intersection: HashSet<_> = a.intersection(&b).cloned().collect();
- /// assert_eq!(intersection, [2, 3].iter().cloned().collect());
+ /// let intersection: HashSet<_> = a.intersection(&b).collect();
+ /// assert_eq!(intersection, [2, 3].iter().collect());
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn intersection<'a>(&'a self, other: &'a HashSet<T, S>) -> Intersection<'a, T, S> {
Intersection {
iter: self.iter(),
- other: other,
+ other,
}
}
@@ -397,8 +413,8 @@ impl<T, S> HashSet<T, S>
/// println!("{}", x);
/// }
///
- /// let union: HashSet<_> = a.union(&b).cloned().collect();
- /// assert_eq!(union, [1, 2, 3, 4].iter().cloned().collect());
+ /// let union: HashSet<_> = a.union(&b).collect();
+ /// assert_eq!(union, [1, 2, 3, 4].iter().collect());
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn union<'a>(&'a self, other: &'a HashSet<T, S>) -> Union<'a, T, S> {
@@ -440,6 +456,22 @@ impl<T, S> HashSet<T, S>
}
/// Clears the set, returning all elements in an iterator.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use std::collections::HashSet;
+ ///
+ /// let mut set: HashSet<_> = [1, 2, 3].iter().cloned().collect();
+ /// assert!(!set.is_empty());
+ ///
+ /// // print 1, 2, 3 in an arbitrary order
+ /// for i in set.drain() {
+ /// println!("{}", i);
+ /// }
+ ///
+ /// assert!(set.is_empty());
+ /// ```
#[inline]
#[stable(feature = "drain", since = "1.6.0")]
pub fn drain(&mut self) -> Drain<T> {
diff --git a/ctr-std/src/collections/hash/table.rs b/ctr-std/src/collections/hash/table.rs
index 3844690..7e623a0 100644
--- a/ctr-std/src/collections/hash/table.rs
+++ b/ctr-std/src/collections/hash/table.rs
@@ -353,14 +353,14 @@ impl<K, V, M: Deref<Target = RawTable<K, V>>> Bucket<K, V, M> {
let ib_index = ib_index & table.capacity_mask;
Bucket {
raw: table.raw_bucket_at(ib_index),
- table: table,
+ table,
}
}
pub fn first(table: M) -> Bucket<K, V, M> {
Bucket {
raw: table.raw_bucket_at(0),
- table: table,
+ table,
}
}
@@ -455,7 +455,7 @@ impl<K, V, M: Deref<Target = RawTable<K, V>>> EmptyBucket<K, V, M> {
match self.next().peek() {
Full(bucket) => {
Ok(GapThenFull {
- gap: gap,
+ gap,
full: bucket,
})
}
@@ -563,7 +563,7 @@ impl<'t, K, V> FullBucket<K, V, &'t mut RawTable<K, V>> {
///
/// This works similarly to `put`, building an `EmptyBucket` out of the
/// taken bucket.
- pub fn take(mut self) -> (EmptyBucket<K, V, &'t mut RawTable<K, V>>, K, V) {
+ pub fn take(self) -> (EmptyBucket<K, V, &'t mut RawTable<K, V>>, K, V) {
self.table.size -= 1;
unsafe {
@@ -717,26 +717,25 @@ fn calculate_offsets(hashes_size: usize,
(pairs_offset, end_of_pairs, oflo)
}
-// Returns a tuple of (minimum required malloc alignment, hash_offset,
+// Returns a tuple of (minimum required malloc alignment,
// array_size), from the start of a mallocated array.
fn calculate_allocation(hash_size: usize,
hash_align: usize,
pairs_size: usize,
pairs_align: usize)
- -> (usize, usize, usize, bool) {
- let hash_offset = 0;
+ -> (usize, usize, bool) {
let (_, end_of_pairs, oflo) = calculate_offsets(hash_size, pairs_size, pairs_align);
let align = cmp::max(hash_align, pairs_align);
- (align, hash_offset, end_of_pairs, oflo)
+ (align, end_of_pairs, oflo)
}
#[test]
fn test_offset_calculation() {
- assert_eq!(calculate_allocation(128, 8, 16, 8), (8, 0, 144, false));
- assert_eq!(calculate_allocation(3, 1, 2, 1), (1, 0, 5, false));
- assert_eq!(calculate_allocation(6, 2, 12, 4), (4, 0, 20, false));
+ assert_eq!(calculate_allocation(128, 8, 16, 8), (8, 144, false));
+ assert_eq!(calculate_allocation(3, 1, 2, 1), (1, 5, false));
+ assert_eq!(calculate_allocation(6, 2, 12, 4), (4, 20, false));
assert_eq!(calculate_offsets(128, 15, 4), (128, 143, false));
assert_eq!(calculate_offsets(3, 2, 4), (4, 6, false));
assert_eq!(calculate_offsets(6, 12, 4), (8, 20, false));
@@ -768,10 +767,10 @@ impl<K, V> RawTable<K, V> {
// This is great in theory, but in practice getting the alignment
// right is a little subtle. Therefore, calculating offsets has been
// factored out into a different function.
- let (alignment, hash_offset, size, oflo) = calculate_allocation(hashes_size,
- align_of::<HashUint>(),
- pairs_size,
- align_of::<(K, V)>());
+ let (alignment, size, oflo) = calculate_allocation(hashes_size,
+ align_of::<HashUint>(),
+ pairs_size,
+ align_of::<(K, V)>());
assert!(!oflo, "capacity overflow");
// One check for overflow that covers calculation and rounding of size.
@@ -784,7 +783,7 @@ impl<K, V> RawTable<K, V> {
let buffer = Heap.alloc(Layout::from_size_align(size, alignment).unwrap())
.unwrap_or_else(|e| Heap.oom(e));
- let hashes = buffer.offset(hash_offset as isize) as *mut HashUint;
+ let hashes = buffer as *mut HashUint;
RawTable {
capacity_mask: capacity.wrapping_sub(1),
@@ -860,8 +859,8 @@ impl<K, V> RawTable<K, V> {
// Replace the marker regardless of lifetime bounds on parameters.
IntoIter {
iter: RawBuckets {
- raw: raw,
- elems_left: elems_left,
+ raw,
+ elems_left,
marker: marker::PhantomData,
},
table: self,
@@ -873,8 +872,8 @@ impl<K, V> RawTable<K, V> {
// Replace the marker regardless of lifetime bounds on parameters.
Drain {
iter: RawBuckets {
- raw: raw,
- elems_left: elems_left,
+ raw,
+ elems_left,
marker: marker::PhantomData,
},
table: Shared::from(self),
@@ -925,7 +924,7 @@ struct RawBuckets<'a, K, V> {
marker: marker::PhantomData<&'a ()>,
}
-// FIXME(#19839) Remove in favor of `#[derive(Clone)]`
+// FIXME(#26925) Remove in favor of `#[derive(Clone)]`
impl<'a, K, V> Clone for RawBuckets<'a, K, V> {
fn clone(&self) -> RawBuckets<'a, K, V> {
RawBuckets {
@@ -976,7 +975,7 @@ pub struct Iter<'a, K: 'a, V: 'a> {
unsafe impl<'a, K: Sync, V: Sync> Sync for Iter<'a, K, V> {}
unsafe impl<'a, K: Sync, V: Sync> Send for Iter<'a, K, V> {}
-// FIXME(#19839) Remove in favor of `#[derive(Clone)]`
+// FIXME(#26925) Remove in favor of `#[derive(Clone)]`
impl<'a, K, V> Clone for Iter<'a, K, V> {
fn clone(&self) -> Iter<'a, K, V> {
Iter {
@@ -1157,6 +1156,7 @@ impl<K: Clone, V: Clone> Clone for RawTable<K, V> {
}
new_ht.size = self.size();
+ new_ht.set_tag(self.tag());
new_ht
}
@@ -1183,10 +1183,10 @@ unsafe impl<#[may_dangle] K, #[may_dangle] V> Drop for RawTable<K, V> {
let hashes_size = self.capacity() * size_of::<HashUint>();
let pairs_size = self.capacity() * size_of::<(K, V)>();
- let (align, _, size, oflo) = calculate_allocation(hashes_size,
- align_of::<HashUint>(),
- pairs_size,
- align_of::<(K, V)>());
+ let (align, size, oflo) = calculate_allocation(hashes_size,
+ align_of::<HashUint>(),
+ pairs_size,
+ align_of::<(K, V)>());
debug_assert!(!oflo, "should be impossible");