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 @ ..] => .., _ => .., } }
Backlinks