-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Warn by default when encountering a statement which only consists of an equality comparison #1812
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
Closed
Changes from all commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
e3d1bca
Add eq-statement-warning RFC
crumblingstatue d2ed1b2
Add two missing code fences
crumblingstatue 5e35c5e
Add RFC 886 as alternative
crumblingstatue 9d4012a
Mention including clippy's `no_effect` lint in rustc as an alternative
crumblingstatue 43ca723
Reword statement about no_effect and false positives
crumblingstatue File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
- Feature Name: eq_statement_warning | ||
- Start Date: 2016-12-07 | ||
- RFC PR: (leave this empty) | ||
- Rust Issue: (leave this empty) | ||
|
||
# Summary | ||
[summary]: #summary | ||
|
||
Warn by default when encountering a statement which only consists of an equality comparison. | ||
|
||
# Motivation | ||
[motivation]: #motivation | ||
|
||
It is easy to accidentally write `==` when one actually meant `=`. | ||
|
||
Consider the following code: | ||
|
||
```rust | ||
fn main() { | ||
let mut a = 10; | ||
println!("A is {}", a); | ||
if 1 == 2 { | ||
a = 20; | ||
} else { | ||
a == 30; // Oops, meant assignment | ||
} | ||
println!("A is now {}", a); // Still 10 | ||
} | ||
``` | ||
|
||
At the time of this RFC, no warning is produced for this code, | ||
making it easy not to notice this mistake. | ||
This can result in wasted time trying to debug a simple mistake. | ||
|
||
We can rectify this by giving a warning to the user. | ||
|
||
I'd like to quote @mbrubeck to provide additional motivation | ||
for why this is a good candidate for an on-by-default builtin lint: | ||
|
||
- It catches a typo that is easy to make and difficult to spot, | ||
and that won't be caught by type checking. | ||
|
||
- It can be very narrowly targeted, only matching statements of the form `EXPR == EXPR;`. | ||
|
||
- False positives are unlikely, because `==` should rarely if ever have side effects, | ||
so it almost never makes sense to discard its result. | ||
|
||
# Detailed design | ||
[design]: #detailed-design | ||
|
||
Add a new lint called `eq_statement`, which checks for statements that are | ||
of the form `lhs == rhs;`. This lint should warn by default. | ||
|
||
The message should tell the user that the result of the equality comparison is not used. | ||
It should also hint that the user probably intended `lhs = rhs`. | ||
Optionally, it can also tell the user that they if they only want the side effects, they | ||
can explicitly express that with `let _ = lhs == rhs;`. | ||
|
||
# Drawbacks | ||
[drawbacks]: #drawbacks | ||
|
||
This adds an additional lint to maintain. | ||
|
||
False positives shouldn't be an issue, as `let _ = rhs == rhs;` expresses the same thing | ||
more explicitly. | ||
|
||
# Alternatives | ||
[alternatives]: #alternatives | ||
|
||
## [RFC 886](https://github.com/rust-lang/rfcs/pull/886) | ||
|
||
[RFC 886](https://github.com/rust-lang/rfcs/pull/886) proposes allowing the `must_use` attribute | ||
on functions. With this, `PartialEq::eq` could be marked `must_use`. | ||
|
||
This RFC was closed, but it should be reconsidered with this use case serving as | ||
additional motivation. | ||
|
||
## Clippy | ||
|
||
Clippy already has a lint that warns about this, called `no_effect`. | ||
|
||
It looks like this: | ||
``` | ||
warning: statement with no effect, #[warn(no_effect)] on by default | ||
--> src/main.rs:7:9 | ||
| | ||
7 | a == 30; // Oops, meant assignment | ||
| ^^^^^^^^ | ||
``` | ||
|
||
However, not everyone uses clippy, and I believe this is a common enough mistake | ||
to justify including a lint for it in rustc itself. | ||
|
||
The `no_effect` lint itself could also be considered for inclusion into rustc | ||
and enabled by default. Note however that `no_effect` is larger in scope than | ||
`eq_statement`, so it is more likely to _potentially_ have false positives, though | ||
none have been found to date. | ||
|
||
# Unresolved questions | ||
[unresolved]: #unresolved-questions | ||
|
||
None. |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
isn't the solution to simply move the lint from clippy to rustc? Together with the
unnecessary_operation
lint for maximal effectThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The
no_effect
lint in clippy has a larger scope than this one, making it more prone to false positives, and less likely to be accepted into rustc. But I'll add merging this lint into rustc as a possible alternative.Since
unnecessary_operation
is not required to solve the problem described in the motivation, it should probably belong in a separate RFC.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
an intermediate solution is to name the rustc lint
no_effect
, only implement your suggesteda == b;
check, and thus ensure that the lint's name will never become obsolete, since it can be extended to more complex situations.