@@ -56,44 +56,33 @@ fn is_zero_const(expr: &Expr<'_>, cx: &LateContext<'_>) -> bool {
5656}
5757
5858impl LateLintPass < ' _ > for IfNotElse {
59- fn check_expr ( & mut self , cx : & LateContext < ' _ > , item : & Expr < ' _ > ) {
60- // While loops will be desugared to ExprKind::If. This will cause the lint to fire.
61- // To fix this, return early if this span comes from a macro or desugaring.
62- if item. span . from_expansion ( ) {
63- return ;
64- }
65- if let ExprKind :: If ( cond, _, Some ( els) ) = item. kind {
66- if let ExprKind :: Block ( ..) = els. kind {
67- // Disable firing the lint in "else if" expressions.
68- if is_else_clause ( cx. tcx , item) {
69- return ;
70- }
59+ fn check_expr ( & mut self , cx : & LateContext < ' _ > , e : & Expr < ' _ > ) {
60+ if let ExprKind :: If ( cond, _, Some ( els) ) = e. kind
61+ && let ExprKind :: DropTemps ( cond) = cond. kind
62+ && let ExprKind :: Block ( ..) = els. kind
63+ {
64+ let ( msg, help) = match cond. kind {
65+ ExprKind :: Unary ( UnOp :: Not , _) => (
66+ "unnecessary boolean `not` operation" ,
67+ "remove the `!` and swap the blocks of the `if`/`else`" ,
68+ ) ,
69+ // Don't lint on `… != 0`, as these are likely to be bit tests.
70+ // For example, `if foo & 0x0F00 != 0 { … } else { … }` is already in the "proper" order.
71+ ExprKind :: Binary ( op, _, rhs) if op. node == BinOpKind :: Ne && !is_zero_const ( rhs, cx) => (
72+ "unnecessary `!=` operation" ,
73+ "change to `==` and swap the blocks of the `if`/`else`" ,
74+ ) ,
75+ _ => return ,
76+ } ;
7177
72- match cond. peel_drop_temps ( ) . kind {
73- ExprKind :: Unary ( UnOp :: Not , _) => {
74- span_lint_and_help (
75- cx,
76- IF_NOT_ELSE ,
77- item. span ,
78- "unnecessary boolean `not` operation" ,
79- None ,
80- "remove the `!` and swap the blocks of the `if`/`else`" ,
81- ) ;
82- } ,
83- ExprKind :: Binary ( ref kind, _, lhs) if kind. node == BinOpKind :: Ne && !is_zero_const ( lhs, cx) => {
84- // Disable firing the lint on `… != 0`, as these are likely to be bit tests.
85- // For example, `if foo & 0x0F00 != 0 { … } else { … }` already is in the "proper" order.
86- span_lint_and_help (
87- cx,
88- IF_NOT_ELSE ,
89- item. span ,
90- "unnecessary `!=` operation" ,
91- None ,
92- "change to `==` and swap the blocks of the `if`/`else`" ,
93- ) ;
94- } ,
95- _ => ( ) ,
96- }
78+ // `from_expansion` will also catch `while` loops which appear in the HIR as:
79+ // ```rust
80+ // loop {
81+ // if cond { ... } else { break; }
82+ // }
83+ // ```
84+ if !e. span . from_expansion ( ) && !is_else_clause ( cx. tcx , e) {
85+ span_lint_and_help ( cx, IF_NOT_ELSE , e. span , msg, None , help) ;
9786 }
9887 }
9988 }
0 commit comments