Skip to content

Conversation

surechen
Copy link
Contributor

@surechen surechen commented Sep 30, 2021

fixes #7731

Make if_then_panic handle situation of cond.kind = ExprKind::DropTemps(ExprKind::Binary(BinOpKind::And || BinOpKind::Or, left, right), ..) =

changelog: [if_then_panic] Fix suggestion for more complex conditions

Make if_then_else handle situation of cond.kind = ExprKind::DropTemps(ExprKind::Binary(BinOpKind::And || BinOpKind::Or, left, right), ..) =
@surechen surechen changed the title Make if_then_else handle situation of BinOpKind::And || BinOpKind::Or Make if_then_panic handle situation of BinOpKind::And || BinOpKind::Or Sep 30, 2021
@surechen
Copy link
Contributor Author

fixes #7731

Make if_then_panic handle situation of cond.kind = ExprKind::DropTemps(ExprKind::Binary(BinOpKind::And || BinOpKind::Or, left, right), ..) =

Hello, @flip1995. There is no automatic allocation of reviewer, I do not know how to deal with it, can you help me? Thank you

@flip1995
Copy link
Member

There is no automatic allocation of reviewer

That's weird. I just self-assign it to me :)

@flip1995
Copy link
Member

r? @flip1995

(FYI @surechen this is how you can assign/request a specific reviewer)

@flip1995
Copy link
Member

I think your solution is more difficult than it has to be. The easiest fix for this would be to put the expr in if <expr> into parentheses and be done with it. You can do that more easily by just using clippy_utils::Sugg. There should be a maybe_paren function somewhere in there that will at parenthesis to the suggestion, if necessary.

@giraffate giraffate added the S-waiting-on-author Status: This is awaiting some action from the author. (Use `@rustbot ready` to update this status) label Sep 30, 2021
@teor2345
Copy link
Contributor

teor2345 commented Oct 1, 2021

I think your solution is more difficult than it has to be. The easiest fix for this would be to put the expr in if <expr> into parentheses and be done with it. You can do that more easily by just using clippy_utils::Sugg. There should be a maybe_paren function somewhere in there that will at parenthesis to the suggestion, if necessary.

This would also handle operators like == and !=, and other complex expressions.

Edit: there doesn't seem to be a simplification for !(a != b) -> a == b, but that's a totally separate issue.

@surechen
Copy link
Contributor Author

surechen commented Oct 1, 2021

I think your solution is more difficult than it has to be. The easiest fix for this would be to put the expr in if <expr> into parentheses and be done with it. You can do that more easily by just using clippy_utils::Sugg. There should be a maybe_paren function somewhere in there that will at parenthesis to the suggestion, if necessary.

Hi, Done. clippy_utils::Sugg is very cool. Thank you very much.

@surechen
Copy link
Contributor Author

surechen commented Oct 1, 2021

I think your solution is more difficult than it has to be. The easiest fix for this would be to put the expr in if <expr> into parentheses and be done with it. You can do that more easily by just using clippy_utils::Sugg. There should be a maybe_paren function somewhere in there that will at parenthesis to the suggestion, if necessary.

This would also handle operators like == and !=, and other complex expressions.

Edit: there doesn't seem to be a simplification for !(a != b) -> a == b, but that's a totally separate issue.

Agree, the various possibilities here are very complicated. Using sugg is better than trying to cover various possible situations in this lint.

Comment on lines +77 to +84
let cond_sugg = if let ExprKind::DropTemps(e, ..) = cond.kind {
if let Expr{kind: ExprKind::Unary(UnOp::Not, not_expr), ..} = e {
sugg::Sugg::hir_with_applicability(cx, not_expr, "..", &mut applicability).maybe_par().to_string()
} else {
format!("!{}", sugg::Sugg::hir_with_applicability(cx, e, "..", &mut applicability).maybe_par().to_string())
}
} else {
format!("!{}", snippet_with_applicability(cx, cond.span, "..", &mut applicability))
format!("!{}", sugg::Sugg::hir_with_applicability(cx, cond, "..", &mut applicability).maybe_par().to_string())
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cond and e should have the same Span , so the two format! calls are pretty much equivalent. I think you only have to change the else case and not the ExprKind::Unary case.

Copy link
Contributor Author

@surechen surechen Oct 1, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cond and e should have the same Span , so the two format! calls are pretty much equivalent. I think you only have to change the else case and not the ExprKind::Unary case.

Hi, I thought the same at the beginning, but if I only modify the else block:

let cond_sugg = if let ExprKind::DropTemps(Expr{kind: ExprKind::Unary(UnOp::Not, not_expr), ..}, ..) = cond.kind {
     sugg::Sugg::hir_with_applicability(cx, not_expr, "..", &mut applicability).maybe_par().to_string()
} else {
     format!("!{}", sugg::Sugg::hir_with_applicability(cx, cond, "..", &mut applicability).maybe_par().to_string())
};

result will be like this:

error: only a `panic!` in `if`-then statement
  --> $DIR/if_then_panic.rs:45:5
   |
LL | /     if a.is_empty() && !b.is_empty() {
LL | |         panic!("panic3");
LL | |     }
   | |_____^ help: try: `assert!(!a.is_empty() && !b.is_empty(), "panic3");`

So I think "a.is_empty() && !b.is_empty()" is ExprKind::DropTemps{Expr{kind: ExprKind::Binary(BinOpKind::And, left, right), ..}} here.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm, that's weird. I also just tested it locally. In that case, let's merge it as it is.

@flip1995
Copy link
Member

flip1995 commented Oct 1, 2021

Edit: there doesn't seem to be a simplification for !(a != b) -> a == b, but that's a totally separate issue.

@teor2345 There is the nonminimal_bool lint that should take care of this. But this lint is a bit restricted, since simplifying logical expressions is a NP-hard problem (or checking if two expressions are equivalent or something like that...).

@flip1995
Copy link
Member

flip1995 commented Oct 1, 2021

@bors r+

Thanks!

@bors
Copy link
Contributor

bors commented Oct 1, 2021

📌 Commit 41e2c68 has been approved by flip1995

@bors
Copy link
Contributor

bors commented Oct 1, 2021

⌛ Testing commit 41e2c68 with merge b48ba90...

bors added a commit that referenced this pull request Oct 1, 2021
Make if_then_panic handle situation of BinOpKind::And || BinOpKind::Or

fixes #7731

Make if_then_panic handle situation of cond.kind = ExprKind::DropTemps(ExprKind::Binary(BinOpKind::And || BinOpKind::Or, left, right), ..) =
@bors
Copy link
Contributor

bors commented Oct 1, 2021

💔 Test failed - checks-action_test

@flip1995
Copy link
Member

flip1995 commented Oct 1, 2021

@bors retry (added changelog)

@bors
Copy link
Contributor

bors commented Oct 1, 2021

⌛ Testing commit 41e2c68 with merge fe999e8...

@bors
Copy link
Contributor

bors commented Oct 1, 2021

☀️ Test successful - checks-action_dev_test, checks-action_remark_test, checks-action_test
Approved by: flip1995
Pushing fe999e8 to master...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-author Status: This is awaiting some action from the author. (Use `@rustbot ready` to update this status)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

if-then-panic suggestion is not equivalent for complex conditions
5 participants