Power-users of Rust are certainly aware of the dilemma that in match arms, patterns like foo => ...
can either match anything and bind to foo, or match a constant or enum case called foo
. This can make code difficult to read, and often causes confusion about which option is actually happening.
Naming conventions don't fully solve the issue. For example, if you're refactoring and you accidentally move a constant named FOO
out of scope, all of a sudden FOO => ...
will be matched by assigning FOO
as a variable, which may lead to confusing errors... or even incorrect code with just two misleading, spurious-looking warnings about naming conventions and an unused variable.
Also: many users commonly try to match something to the value of an existing variable like foo => ...
instead of x if x == foo => ...
. When that happens, very unintuitively the match always succeeds and just replaces/shadows foo
with whatever was matched. In fact, this post is inspired by one such victim on Reddit.
Due to this, IMHO it would be a lot clearer if we style-linted against direct binding and suggest that users switch to adding the extra few characters for @ _
. It would make the code clearer to read, mitigate the constant-out-of-scope case, and make it easier for new users to figure out what went wrong if they attempt this common mistake. In other words, I'm arguing for reversing the clippy::redundant_pattern
lint to suggest changing match arms from foo => ...
to foo @ _ => ...
; then, only constants and enum cases are meant to use the FOO => ...
syntax.
Curious to hear what people think about this idea? Is there an already an RFC for this?