RFC 2005 (a.k.a. match ergonomics) introduced the rule.
Before the change was implemented, there were 2 ways to write this match
.
-
Match on
self
and prefix each pattern with&
to “destructure” the reference.fn tail(&self) -> Option<&Foo> { match self { &Cons(_, ref item) => Some(item), &Nil => None, } }
-
Match on
*self
and don’t prefix each pattern with&
(because*self
is not a reference).fn tail(&self) -> Option<&Foo> { match *self { Cons(_, ref item) => Some(item), Nil => None, } }
Yet, in both cases, we need to write ref item
, otherwise we’ll get error[E0507]: cannot move out of borrowed content
.
However, in the match
you’ve written, the expression being matched is a reference (type &List
) but the patterns are not reference patterns (as in 1. above). This is where match ergonomics kick in: the rule says that when a reference is matched with a non-reference pattern, the bindings within that pattern bind by reference rather than by value (i.e. as if they were prefixed with ref
).