2 use std::collections::{HashMap, HashSet};
3 use std::hash::{Hash, Hasher};
4 use std::sync::atomic::{AtomicUsize, Ordering::Relaxed};
6 struct Key(AtomicUsize);
9 fn clone(&self) -> Self {
10 Key(AtomicUsize::new(self.0.load(Relaxed)))
14 impl PartialEq for Key {
15 fn eq(&self, other: &Self) -> bool {
16 self.0.load(Relaxed) == other.0.load(Relaxed)
23 fn hash<H: Hasher>(&self, h: &mut H) {
24 self.0.load(Relaxed).hash(h);
28 fn should_not_take_this_arg(m: &mut HashMap<Key, usize>, _n: usize) -> HashSet<Key> {
29 let _other: HashMap<Key, bool> = HashMap::new();
30 m.keys().cloned().collect()
33 fn this_is_ok(_m: &mut HashMap<usize, Key>) {}
35 // Raw pointers are hashed by the address they point to, so it doesn't matter if they point to a
36 // type with interior mutability. See:
37 // - clippy issue: https://github.com/rust-lang/rust-clippy/issues/6745
38 // - std lib: https://github.com/rust-lang/rust/blob/1.54.0/library/core/src/hash/mod.rs#L717-L736
40 fn raw_ptr_is_ok(_m: &mut HashMap<*const Key, ()>) {}
41 fn raw_mut_ptr_is_ok(_m: &mut HashMap<*mut Key, ()>) {}
47 fn trait_fn(&self, set: HashSet<Self::AssociatedType>);
50 fn generics_are_ok_too<K>(_m: &mut HashSet<K>) {
51 // nothing to see here, move along
54 fn tuples<U>(_m: &mut HashMap<((), U), ()>) {}
56 fn tuples_bad<U>(_m: &mut HashMap<(Key, U), bool>) {}
59 let _ = should_not_take_this_arg(&mut HashMap::new(), 1);
60 this_is_ok(&mut HashMap::new());
61 tuples::<Key>(&mut HashMap::new());
62 tuples::<()>(&mut HashMap::new());
63 tuples_bad::<()>(&mut HashMap::new());
65 raw_ptr_is_ok(&mut HashMap::new());
66 raw_mut_ptr_is_ok(&mut HashMap::new());