pub struct RefMut<'a, T: IdHashItem, S: Clone + BuildHasher = DefaultHashBuilder> { /* private fields */ }
Expand description
A mutable reference to an IdHashMap
item.
This is a wrapper around a &mut T
that panics when dropped, if the
borrowed value’s keys have changed since the wrapper was created.
§Change detection
It is illegal to change the key of a borrowed &mut T
. RefMut
attempts to
enforce this invariant.
RefMut
stores the Hash
output of the key at creation time, and
recomputes this hash when it is dropped or when Self::into_ref
is
called. If a key changes, there’s a small but non-negligible chance that its
hash value stays the same1. In that case, as long as the
new key is not the same as another existing one, internal invariants are not
violated and the IdHashMap
will continue to work correctly. (But don’t
rely on this!)
It is also possible to deliberately write pathological Hash
implementations that collide more often. (Don’t do this either.)
Also, RefMut
’s hash detection will not function if mem::forget
is
called on it. If the key is changed and mem::forget
is then called on the
RefMut
, the IdHashMap
will stop functioning correctly. This will not
introduce memory safety issues, however.
The issues here are similar to using interior mutability (e.g. RefCell
or
Mutex
) to mutate keys in a regular HashMap
.
The output of
Hash
is au64
, so the probability of an individual hash colliding by chance is 1/2⁶⁴. Due to the birthday problem, the probability of a collision by chance reaches 10⁻⁶ within around 6 × 10⁶ elements. ↩