Struct RefMut

Source
pub struct RefMut<'a, T: IdOrdItem>
where T::Key<'a>: Hash,
{ /* private fields */ }
Expand description

A mutable reference to an IdOrdMap entry.

This is a wrapper around a &mut T that panics when dropped, if the borrowed value’s key has changed since the wrapper was created.

§Change detection

It is illegal to change the keys of a borrowed &mut T. RefMut attempts to enforce this invariant, and as part of that, it requires that the key type implement Hash.

RefMut stores the Hash output of keys at creation time, and recomputes these hashes 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, the map will no longer function correctly and might panic on access. This will not introduce memory safety issues, however.

It is also possible to deliberately write pathological Hash implementations that collide more often. (Don’t do this.)

Also, RefMut’s hash detection will not function if mem::forget is called on it. If a key is changed and mem::forget is then called on the RefMut, the IdOrdMap will no longer function correctly and might panic on access. 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.


  1. The output of Hash is a u64, 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. 

Implementations§

Source§

impl<'a, T: IdOrdItem> RefMut<'a, T>
where T::Key<'a>: Hash,

Source

pub fn into_ref(self) -> &'a T

Converts this RefMut into a &'a T.

Source§

impl<'a, T: IdOrdItem> RefMut<'a, T>
where for<'k> T::Key<'k>: Hash,

Source

pub fn reborrow<'b>(&'b mut self) -> RefMut<'b, T>

Borrows self into a shorter-lived RefMut.

This RefMut will also check hash equality on drop.

Note: currently, due to limitations in the Rust borrow checker, this effectively requires that T: 'static. Relaxing this requirement should be possible in principle.

Trait Implementations§

Source§

impl<'a, T: IdOrdItem + Debug> Debug for RefMut<'a, T>
where T::Key<'a>: Hash,

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<'a, T: IdOrdItem> Deref for RefMut<'a, T>
where T::Key<'a>: Hash,

Source§

type Target = T

The resulting type after dereferencing.
Source§

fn deref(&self) -> &Self::Target

Dereferences the value.
Source§

impl<'a, T: IdOrdItem> DerefMut for RefMut<'a, T>
where T::Key<'a>: Hash,

Source§

fn deref_mut(&mut self) -> &mut Self::Target

Mutably dereferences the value.
Source§

impl<'a, T: IdOrdItem> Drop for RefMut<'a, T>
where T::Key<'a>: Hash,

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more

Auto Trait Implementations§

§

impl<'a, T> Freeze for RefMut<'a, T>

§

impl<'a, T> RefUnwindSafe for RefMut<'a, T>
where T: RefUnwindSafe,

§

impl<'a, T> Send for RefMut<'a, T>
where T: Send,

§

impl<'a, T> Sync for RefMut<'a, T>
where T: Sync,

§

impl<'a, T> Unpin for RefMut<'a, T>

§

impl<'a, T> !UnwindSafe for RefMut<'a, T>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<P, T> Receiver for P
where P: Deref<Target = T> + ?Sized, T: ?Sized,

Source§

type Target = T

🔬This is a nightly-only experimental API. (arbitrary_self_types)
The target type on which the method may be called.
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.