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?