Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Deref/DerefMut Desugarings

The expression *$expr is allowed if $expr is a built-in reference type (&T, &mut T, *const T, *mut T and Box<T>), or if $expr: T and T: core::ops::Deref. In this step we desugar the Deref case.

Let T: Deref be a type and $expr be an expression of that type. Let context!(..) be a context in which one may find the expression *$expr.

For each context we figure out an associated mutability: &mut $expr and if let Some(ref mut x) = $expr are two examples of mutable contexts. Uses that don't require mutability are considered immutable contexts. Examples of immutable contexts are &$expr and function_call($expr). For let place p = $expr; assignments, mutability is inferred from the mutability of the contexts in which p is used.

We then desugar as follows:

#![allow(unused)]
fn main() {
context!(*$expr)
// becomes, if the context is considered mutable:
context!(*<T as DerefMut>::deref_mut(&mut $expr))
// otherwise, if the context is considered immutable:
context!(*<T as Deref>::deref(&$expr))
}

For example:

#![allow(unused)]
fn main() {
let arc: Arc<Option<i32>> = ...;
if arc.is_some() { .. }

// becomes, before this step:
if Option::is_some(&*arc) { .. }

// becomes, after this step:
if Option::is_some(&*Deref::deref(&arc)) { .. }
}
#![allow(unused)]
fn main() {
let mut v: Vec<u32> = ...;
match *v {
    [0, ref mut rest @ ..] => ..,
    _ => ..,
}

// becomes, because the pattern context is seen to be mutable:
match *DerefMut::deref_mut(&mut v) {
    [0, ref mut rest @ ..] => ..,
    _ => ..,
}
}