@@ -56,44 +56,33 @@ fn is_zero_const(expr: &Expr<'_>, cx: &LateContext<'_>) -> bool {
56
56
}
57
57
58
58
impl 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
+ } ;
71
77
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) ;
97
86
}
98
87
}
99
88
}
0 commit comments