|
1 | 1 | use crate::utils::{snippet_with_applicability, span_lint_and_sugg};
|
| 2 | +use if_chain::if_chain; |
2 | 3 | use rustc_ast::ast::{BinOpKind, Expr, ExprKind, LitKind, UnOp};
|
3 | 4 | use rustc_errors::Applicability;
|
4 | 5 | use rustc_lint::{EarlyContext, EarlyLintPass};
|
@@ -102,36 +103,36 @@ impl EarlyLintPass for Precedence {
|
102 | 103 | }
|
103 | 104 | }
|
104 | 105 |
|
105 |
| - if let ExprKind::Unary(UnOp::Neg, ref rhs) = expr.kind { |
106 |
| - if let ExprKind::MethodCall(ref path_segment, ref args, _) = rhs.kind { |
| 106 | + if let ExprKind::Unary(UnOp::Neg, operand) = &expr.kind { |
| 107 | + let mut arg = operand; |
| 108 | + |
| 109 | + let mut all_odd = true; |
| 110 | + while let ExprKind::MethodCall(path_segment, args, _) = &arg.kind { |
107 | 111 | let path_segment_str = path_segment.ident.name.as_str();
|
108 |
| - if let Some(slf) = args.first() { |
109 |
| - if let ExprKind::Lit(ref lit) = slf.kind { |
110 |
| - match lit.kind { |
111 |
| - LitKind::Int(..) | LitKind::Float(..) => { |
112 |
| - if ALLOWED_ODD_FUNCTIONS |
113 |
| - .iter() |
114 |
| - .any(|odd_function| **odd_function == *path_segment_str) |
115 |
| - { |
116 |
| - return; |
117 |
| - } |
118 |
| - let mut applicability = Applicability::MachineApplicable; |
119 |
| - span_lint_and_sugg( |
120 |
| - cx, |
121 |
| - PRECEDENCE, |
122 |
| - expr.span, |
123 |
| - "unary minus has lower precedence than method call", |
124 |
| - "consider adding parentheses to clarify your intent", |
125 |
| - format!( |
126 |
| - "-({})", |
127 |
| - snippet_with_applicability(cx, rhs.span, "..", &mut applicability) |
128 |
| - ), |
129 |
| - applicability, |
130 |
| - ); |
131 |
| - }, |
132 |
| - _ => (), |
133 |
| - } |
134 |
| - } |
| 112 | + all_odd &= ALLOWED_ODD_FUNCTIONS |
| 113 | + .iter() |
| 114 | + .any(|odd_function| **odd_function == *path_segment_str); |
| 115 | + arg = args.first().expect("A method always has a receiver."); |
| 116 | + } |
| 117 | + |
| 118 | + if_chain! { |
| 119 | + if !all_odd; |
| 120 | + if let ExprKind::Lit(lit) = &arg.kind; |
| 121 | + if let LitKind::Int(..) | LitKind::Float(..) = &lit.kind; |
| 122 | + then { |
| 123 | + let mut applicability = Applicability::MachineApplicable; |
| 124 | + span_lint_and_sugg( |
| 125 | + cx, |
| 126 | + PRECEDENCE, |
| 127 | + expr.span, |
| 128 | + "unary minus has lower precedence than method call", |
| 129 | + "consider adding parentheses to clarify your intent", |
| 130 | + format!( |
| 131 | + "-({})", |
| 132 | + snippet_with_applicability(cx, operand.span, "..", &mut applicability) |
| 133 | + ), |
| 134 | + applicability, |
| 135 | + ); |
135 | 136 | }
|
136 | 137 | }
|
137 | 138 | }
|
|
0 commit comments