-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Add new lints: manual_and and manual_or
#12832
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
Add new lints: manual_and and manual_or
#12832
Conversation
9d0b00d to
4165cd5
Compare
clippy_lints/src/manual_and.rs
Outdated
| /// ```no_run | ||
| /// if a { | ||
| /// b |
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.
doc test is failling, maybe you meant to use /// ```ignore ?. Or assign values to a and b using:
/// ```no_run
/// # let a = true;
/// # let b = false;
/// if a {
/// b
something like that~
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.
Since manual_and.rs and manual_or.rs shares a lot same code, could you merge them into a single file?
Similar to the structures inside of src/booleans.rs.
clippy_lints/src/manual_or.rs
Outdated
| if let ExprKind::If(cond, then, Some(else_expr)) = expr.kind { | ||
| if contains_let(cond) { | ||
| return; | ||
| } |
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.
I think clippy_utils::higher::If should achieve the same result here.
you could try replacing it with:
use clippy_utils::higher;
if let Some(higher::If { cond, then, r#else: Some(else_expr) }) = higher::If::hir(expr) {
// ...using visitor might seems a bit of overkill
4165cd5 to
66758bc
Compare
|
We made the requested changes |
clippy_lints/src/manual_and_or.rs
Outdated
| if contains_let(cond) { | ||
| return; | ||
| } |
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.
I think this is not needed anymore? yes?
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.
That's true, it's fixed now!
|
(Jarcho has too many PR assigned, I hope this make sense...) r? clippy |
66758bc to
0b884ca
Compare
|
☔ The latest upstream changes (presumably #12849) made this pull request unmergeable. Please resolve the merge conflicts. |
0b884ca to
32b35e7
Compare
|
There are merge commits (commits with multiple parents) in your changes. We have a no merge policy so these commits will need to be removed for this pull request to be merged. You can start a rebase with the following commands: The following commits are merge commits: |
Suggests replacing if-else expressions where one branch is a boolean literal with && / || operators. Co-authored-by: Francisco Salgueiro <[email protected]>
7b68c50 to
3658ef6
Compare
| fn extract_final_expression_snippet<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'tcx>) -> Option<String> { | ||
| if let ExprKind::Block(block, _) = expr.kind { | ||
| if let Some(final_expr) = block.expr { | ||
| return cx.sess().source_map().span_to_snippet(final_expr.span).ok(); |
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.
Can use snippet_opt here & elsewhere
| if contains_or(cond) || contains_or(then) || fetch_bool_expr(then).is_some() { | ||
| return; | ||
| } |
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.
The precedence of the context the if appears in is also significant:
let _ = c == if a { b } else { false };
// becomes
let _ = c == a && b;
// AKA
let _ = (c == a) && b;| return; | ||
| } | ||
| if match then.kind { | ||
| ExprKind::Block(block, _) => !block.stmts.is_empty(), |
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.
We should check that the type of block.expr isn't ! (never), to exclude things like
if a {
return
} else {
false
}The lint isn't semantically incorrect here but a && return is unusual
| .unwrap_or_else(|_| "..".to_string()); | ||
|
|
||
| let then_snippet = extract_final_expression_snippet(cx, then).unwrap_or_else(|| "..".to_string()); | ||
| let suggestion = format!("{cond_snippet} && {then_snippet}"); |
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.
We'll want to handle when the if contains comments -
if a {
// Comment
b
} else {
false
}Preserving them is an option but it might be better to not lint here, if the comment is large it would be weird to have in the middle of an &&/||
There's span_contains_comment to help with this
|
☔ The latest upstream changes (presumably #12873) made this pull request unmergeable. Please resolve the merge conflicts. |
|
Hey @mira-eanda , this is a ping from triage, since there hasn't been any activity in some time. Are you still planning to continue this implementation? If you have any questions, you're always welcome to ask them in this PR or on Zulip. @rustbot author |
|
☔ The latest upstream changes (possibly d28d234) made this pull request unmergeable. Please resolve the merge conflicts. |
|
Closing since there's been no response since the last ping. @mira-eanda if you want to continue working on this feel free to reopen or create a new PR. |
Fixes #12434
Added two new lints:
manual_andthat suggests replacing if-else expressions where one branch is a boolean literal with&&andmanual_orwhich does the same but for the||operator.changelog: new lint: [
manual_and]changelog: new lint: [
manual_or]