Skip to content

Commit

Permalink
Remove unsound use of specialization
Browse files Browse the repository at this point in the history
See rust-lang/rust#67194 for details
  • Loading branch information
Amanieu committed Apr 25, 2020
1 parent 77c11a1 commit 8127703
Showing 1 changed file with 2 additions and 33 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

0 comments on commit 8127703

Please sign in to comment.