DerefMut
/Deref
/Index
/IndexMut
are determined by mutability, which is a different question from lvalue/rvalue context. Mutability makes no sense for rvalue context.
In fact, all four traits require the operand self
to be in an lvalue context, since they all take &Self
or &mut Self
as argument.
DerefMut
/IndexMut
are used whenever mutability is needed, e.g.
*here = ...;
here[i] = ...;
&mut here
&mut here[i]
here.call_some_mut_method(...)
here[i].call_some_mut_method(...)
An lvalue context is where you want to know the address (memory location / reference / ...) of the expression, instead of its value. The place where you need an lvalue.
The left operand of an assignment or compound-assignment expression is an lvalue context, …
here = ...;
here += ...;
… as is the single operand of a unary borrow.
&here
&mut here
let ref ... = here;
// Note: equivalent to `let ... = &here;`
let ref mut ... = here;
// Note: equivalent to `let ... = &mut here;`
Note: This shows an immutable lvalue context
The discriminant or subject of a match expression may be an lvalue context, if ref bindings are made, but is otherwise an rvalue context.
match here {
Ok(ref ...) => ...,
Err(ref mut ...) => ...,
}