Strange footgun when adding `mut` to binding

FWIW, this behavior is documented in the Reference (emphasis mine):

If a binding pattern does not explicitly have ref, ref mut, or mut, then it uses the default binding mode to determine how the variable is bound. The default binding mode starts in "move" mode which uses move semantics. When matching a pattern, the compiler starts from the outside of the pattern and works inwards. Each time a reference is matched using a non-reference pattern, it will automatically dereference the value and update the default binding mode. References will set the default binding mode to ref. Mutable references will set the mode to ref mut unless the mode is already ref in which case it remains ref. If the automatically dereferenced value is still a reference, it is dereferenced and this process repeats.

So there's four types of binding patterns:

  • name: an immutable binding with the default binding mode, which resolves to either a move binding or reference binding using match ergonomics.
  • mut name: a mutable move binding.
  • ref name: an immutable reference binding.
  • ref mut name: a mutable reference binding.

It's definitely pretty odd that mut name always resolves to a move binding instead of using the default binding mode.

8 Likes