New lint: always_true_conditions#14434
New lint: always_true_conditions#14434Dominic-Moser wants to merge 2 commits intorust-lang:masterfrom
Conversation
|
r? @Alexendoo rustbot has assigned @Alexendoo. Use |
|
The lintcheck results shows 64 hits, which seem to be all false positives. |
|
@Dominic-Moser Do you plan to continue working on this lint? |
|
Reminder, once the PR becomes ready for a review, use |
|
@rustbot ready, sorry school's been hitting hard |
|
never mind, I have to to checks to make sure the same variable is being used throughout the whole expression |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
|
@samueltardieu I am so confused right now, I keep trying to rebase and it keeps saying I need to rebase. I am sure this is my fault but i have no clue how to fix this... |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
|
Your first commit contains a lot of unrelated changes 9ce8566 What I would do is first reset your branch to the current state of git fetch upstream
git reset --hard upstream/masterThen grab the main parts of the PR - the lint and the test file git checkout b55d82f89c1b29f25044aeaafbbdb7a241c82c3b -- clippy_lints/src/always_true_conditions.rs tests/ui/always_true_conditions.rsNow you can run |
|
@rustbot ready |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
5d5c8e2 to
800a3f7
Compare
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This lint aims to flag a common mistake where a variable is compared against two primitives using a != operator and mistakenly linked with the || with always evaluate to true. ex. ```a != 1 || a != 2``` This helps flag a common mistake and maintain overall quality of code. changelog: new lint
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
| if new_op.node == BinOpKind::Or { | ||
| let f = context_applicable(new_f); | ||
| let l = context_applicable(new_l); | ||
| if l == f { l } else { None } |
There was a problem hiding this comment.
What's the purpose of the Or branch here? If you remove the new_op.node == BinOpKind::Or branch no tests fail
| if let ExprKind::Binary(f_op_kind, f_cond, l_cond) = e.kind | ||
| && let BinOpKind::Or = f_op_kind.node | ||
| { | ||
| let msg = "expression will always be true, did you mean to use &&?"; |
There was a problem hiding this comment.
The "did you mean" can be split out into a help message with https://doc.rust-lang.org/nightly/nightly-rustc/clippy_utils/diagnostics/fn.span_lint_and_help.html
Could also mention that it might be the wrong variable being compared
| let f_res = context_applicable(f_cond); | ||
| let l_res = context_applicable(l_cond); |
There was a problem hiding this comment.
What do f and l stand for here? If there's no good name l/lhs and r/rhs are fairly typical
There was a problem hiding this comment.
It would be good if you could move the implementation of the lint into clippy_lints/src/operators since it would fit well there
| if f_res.is_some() && (l_res == f_res) { | ||
| span_lint(cx, ALWAYS_TRUE_CONDITIONS, e.span, msg); | ||
| } |
There was a problem hiding this comment.
A case to consider would be a != 1 || a != 1 from e.g. a copy/paste, the lint currently says that it's always true which isn't the case
| declare_clippy_lint! { | ||
| /// ### What it does | ||
| /// | ||
| /// Flags a relativly common error where users comparing a varible to a primative use || instal of && in conjunction |
There was a problem hiding this comment.
Will resolve ASAP! 😅 I've had alot of coursework but Ill try to have Alexendoo's suggestions done tonight in conjunction with this.
Knew I shouldnt have cheated on my 8th grade spelling tests...
| /// Flags a relativly common error where users comparing a varible to a primative use || instal of && in conjunction | ||
| /// with !=. This lint was originally meant for simple n != 1 || n != 2 type statements, but the lint will detect | ||
| /// the primitive and varible in any order for any length, as long as the variable stays the same, and the condition | ||
| /// is always 1 primitive and 1 varible. | ||
| /// | ||
| /// ### Why is this bad? | ||
| /// | ||
| ///This is bad because the code will always result in true. If this is intentional a constant can be used in the | ||
| ///case of a boolean varibale assignment, or code in an if block should just be moved outside with comments | ||
| ///explaining why. |
There was a problem hiding this comment.
| /// Flags a relativly common error where users comparing a varible to a primative use || instal of && in conjunction | |
| /// with !=. This lint was originally meant for simple n != 1 || n != 2 type statements, but the lint will detect | |
| /// the primitive and varible in any order for any length, as long as the variable stays the same, and the condition | |
| /// is always 1 primitive and 1 varible. | |
| /// | |
| /// ### Why is this bad? | |
| /// | |
| ///This is bad because the code will always result in true. If this is intentional a constant can be used in the | |
| ///case of a boolean varibale assignment, or code in an if block should just be moved outside with comments | |
| ///explaining why. | |
| /// Flags a relatively common error, where users comparing a variable to a primitive use `||` instead of `&&`, in conjunction | |
| /// with `!=`. This lint was originally meant for simple `n != 1 || n != 2` type expressions, but the lint will now detect | |
| /// the primitive and variable in any order for any length, as long as the variable stays the same, and the conditional | |
| /// is always made of 1 primitive and 1 variable. | |
| /// | |
| /// ### Why is this bad? | |
| /// | |
| /// This is bad because however complex this expression is, its meaning is the same - `true`, and thus | |
| /// the code can be greatly simplified by replacing it with that value. |
Hey, cool lint! (and sorry for the double ping; my suggestion was much shorter 20 minutes ago). I found some typos and some stuff that might not have been very clear. I tried my best to make it easier to read.
The only bit where I'm not sure I understand what is meant is this one:
as long as the variable stays the same
You mean that the variable doesn't change its value? Or do you mean that the variable in question is always the same, like x appearing in multiple parts of the expression, perhaps?
Regardless, I'll see if there's anything else I can help you with. I love the area of symbolic evaluation :)
|
This might be bikeshedding, dunno. First I wanna say that this is a good lint. But I would change the name of the lint to something of a smaller scope.
Finding whether expressions are always true is exceedingly useful (even if one will never find all of them due to undecidability), and is something that people will definitely want to use. However, that's a much larger lint, one that probably requires an engine of its own. Instead of "always true conditions", perhaps something along the lines of "trivial disjunction" could express the scope of this lint better? (There's probably a better one, since there are other disjunctions that are trivial as well. But perhaps it's a good start?) |
That seems like a much better match! To make it only apply to this small lint would 'trivial_var_primitive_disjunction' be a good name? I cant really differentiate between a space a slash but the meaning is "trivial variable/primitive disjunction." |
|
This PR was rebased onto a different master commit. Here's a range-diff highlighting what actually changed. Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers. |
This comment has been minimized.
This comment has been minimized.
This lint aims to flag a common mistake where a variable is compared against two primitives using a != operator and mistakenly linked with the || with always evaluate to true. ex. ```a != 1 || a != 2``` This helps flag a common mistake and maintain overall quality of code. changelog: new lint Hopefully final fix. added a variety of checking, but mostly made sure that the lit.node's were NOT equal to avoid the x!=1 || 1!=x. .
|
☔ The latest upstream changes (possibly #15979) made this pull request unmergeable. Please resolve the merge conflicts. |
This lint closes #1593
This is my first lint, please let me know if I messed something up anywhere!
changelog: [always_true_conditions]: add new lint