Skip to content

Commit

Permalink
Auto merge of #154 - Amanieu:spec2, r=Amanieu
Browse files Browse the repository at this point in the history
Remove unsound use of specialization

Basically the issue is that specialization does not currently take lifetimes into account.

See rust-lang/rust#45982 for details.
  • Loading branch information
bors committed Apr 25, 2020
2 parents 77c11a1 + 5d9e72a commit 265613f
Show file tree
Hide file tree
Showing 2 changed files with 3 additions and 34 deletions.
35 changes: 2 additions & 33 deletions src/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -202,41 +202,10 @@ impl<K: Clone, V: Clone, S: Clone> Clone for HashMap<K, V, S> {
}

fn clone_from(&mut self, source: &Self) {
// We clone the hash_builder first since this might panic and we don't
// want the table to have elements hashed with the wrong hash_builder.
let hash_builder = source.hash_builder.clone();

// For backward-compatibility reasons we can't make the Clone impl
// depend on K: Hash + Eq and S: BuildHasher. However we can exploit
// this using specialization, which allows us to reuse the existing
// storage of the current HashMap to insert the cloned elements into.
trait HashClone<S> {
fn clone_from(&mut self, source: &Self, hash_builder: &S);
}
impl<K: Clone, V: Clone, S> HashClone<S> for HashMap<K, V, S> {
#[cfg_attr(feature = "inline-more", inline)]
default_fn! {
fn clone_from(&mut self, source: &Self, _hash_builder: &S) {
self.table.clone_from(&source.table);
}
}
}
#[cfg(feature = "nightly")]
impl<K: Clone, V: Clone, S> HashClone<S> for HashMap<K, V, S>
where
K: Eq + Hash,
S: BuildHasher,
{
#[cfg_attr(feature = "inline-more", inline)]
fn clone_from(&mut self, source: &Self, hash_builder: &S) {
self.table
.clone_from_with_hasher(&source.table, |x| make_hash(hash_builder, &x.0));
}
}
HashClone::clone_from(self, source, &hash_builder);
self.table.clone_from(&source.table);

// Update hash_builder only if we successfully cloned all elements.
self.hash_builder = hash_builder;
self.hash_builder.clone_from(&source.hash_builder);
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/raw/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1113,7 +1113,7 @@ impl<T: Clone> RawTable<T> {
}

/// Variant of `clone_from` to use when a hasher is available.
#[cfg(any(feature = "nightly", feature = "raw"))]
#[cfg(feature = "raw")]
pub fn clone_from_with_hasher(&mut self, source: &Self, hasher: impl Fn(&T) -> u64) {
// If we have enough capacity in the table, just clear it and insert
// elements one by one. We don't do this if we have the same number of
Expand Down

0 comments on commit 265613f

Please sign in to comment.