@@ -9,6 +9,8 @@ use rustc_errors::Applicability;
99use rustc_hir:: { BinOpKind , Expr , ExprKind , UnOp } ;
1010use rustc_lint:: { LateContext , LateLintPass } ;
1111use rustc_session:: { declare_lint_pass, declare_tool_lint} ;
12+ use rustc_span:: source_map:: Spanned ;
13+
1214use std:: f32:: consts as f32_consts;
1315use std:: f64:: consts as f64_consts;
1416use sugg:: { format_numeric_literal, Sugg } ;
@@ -138,26 +140,29 @@ fn check_log_base(cx: &LateContext<'_, '_>, expr: &Expr<'_>, args: &[Expr<'_>])
138140// TODO: Lint expressions of the form `(x + y).ln()` where y > 1 and
139141// suggest usage of `(x + (y - 1)).ln_1p()` instead
140142fn check_ln1p ( cx : & LateContext < ' _ , ' _ > , expr : & Expr < ' _ > , args : & [ Expr < ' _ > ] ) {
141- if_chain ! {
142- if let ExprKind :: Binary ( op, ref lhs, ref rhs) = & args[ 0 ] . kind;
143- if op. node == BinOpKind :: Add ;
144- then {
145- let recv = match ( constant( cx, cx. tables, lhs) , constant( cx, cx. tables, rhs) ) {
146- ( Some ( ( value, _) ) , _) if F32 ( 1.0 ) == value || F64 ( 1.0 ) == value => rhs,
147- ( _, Some ( ( value, _) ) ) if F32 ( 1.0 ) == value || F64 ( 1.0 ) == value => lhs,
148- _ => return ,
149- } ;
143+ if let ExprKind :: Binary (
144+ Spanned {
145+ node : BinOpKind :: Add , ..
146+ } ,
147+ lhs,
148+ rhs,
149+ ) = & args[ 0 ] . kind
150+ {
151+ let recv = match ( constant ( cx, cx. tables , lhs) , constant ( cx, cx. tables , rhs) ) {
152+ ( Some ( ( value, _) ) , _) if F32 ( 1.0 ) == value || F64 ( 1.0 ) == value => rhs,
153+ ( _, Some ( ( value, _) ) ) if F32 ( 1.0 ) == value || F64 ( 1.0 ) == value => lhs,
154+ _ => return ,
155+ } ;
150156
151- span_lint_and_sugg(
152- cx,
153- SUBOPTIMAL_FLOPS ,
154- expr. span,
155- "ln(1 + x) can be computed more accurately" ,
156- "consider using" ,
157- format!( "{}.ln_1p()" , prepare_receiver_sugg( cx, recv) ) ,
158- Applicability :: MachineApplicable ,
159- ) ;
160- }
157+ span_lint_and_sugg (
158+ cx,
159+ SUBOPTIMAL_FLOPS ,
160+ expr. span ,
161+ "ln(1 + x) can be computed more accurately" ,
162+ "consider using" ,
163+ format ! ( "{}.ln_1p()" , prepare_receiver_sugg( cx, recv) ) ,
164+ Applicability :: MachineApplicable ,
165+ ) ;
161166 }
162167}
163168
@@ -249,8 +254,7 @@ fn check_powf(cx: &LateContext<'_, '_>, expr: &Expr<'_>, args: &[Expr<'_>]) {
249254// and suggest usage of `x.exp_m1() - (y - 1)` instead
250255fn check_expm1 ( cx : & LateContext < ' _ , ' _ > , expr : & Expr < ' _ > ) {
251256 if_chain ! {
252- if let ExprKind :: Binary ( op, ref lhs, ref rhs) = expr. kind;
253- if op. node == BinOpKind :: Sub ;
257+ if let ExprKind :: Binary ( Spanned { node: BinOpKind :: Sub , .. } , ref lhs, ref rhs) = expr. kind;
254258 if cx. tables. expr_ty( lhs) . is_floating_point( ) ;
255259 if let Some ( ( value, _) ) = constant( cx, cx. tables, rhs) ;
256260 if F32 ( 1.0 ) == value || F64 ( 1.0 ) == value;
@@ -276,8 +280,7 @@ fn check_expm1(cx: &LateContext<'_, '_>, expr: &Expr<'_>) {
276280
277281fn is_float_mul_expr < ' a > ( cx : & LateContext < ' _ , ' _ > , expr : & ' a Expr < ' a > ) -> Option < ( & ' a Expr < ' a > , & ' a Expr < ' a > ) > {
278282 if_chain ! {
279- if let ExprKind :: Binary ( op, ref lhs, ref rhs) = & expr. kind;
280- if let BinOpKind :: Mul = op. node;
283+ if let ExprKind :: Binary ( Spanned { node: BinOpKind :: Mul , .. } , ref lhs, ref rhs) = & expr. kind;
281284 if cx. tables. expr_ty( lhs) . is_floating_point( ) ;
282285 if cx. tables. expr_ty( rhs) . is_floating_point( ) ;
283286 then {
@@ -289,34 +292,37 @@ fn is_float_mul_expr<'a>(cx: &LateContext<'_, '_>, expr: &'a Expr<'a>) -> Option
289292}
290293
291294// TODO: Fix rust-lang/rust-clippy#4735
292- fn check_fma ( cx : & LateContext < ' _ , ' _ > , expr : & Expr < ' _ > ) {
293- if_chain ! {
294- if let ExprKind :: Binary ( op, lhs, rhs) = & expr. kind;
295- if let BinOpKind :: Add = op. node;
296- then {
297- let ( recv, arg1, arg2) = if let Some ( ( inner_lhs, inner_rhs) ) = is_float_mul_expr( cx, lhs) {
298- ( inner_lhs, inner_rhs, rhs)
299- } else if let Some ( ( inner_lhs, inner_rhs) ) = is_float_mul_expr( cx, rhs) {
300- ( inner_lhs, inner_rhs, lhs)
301- } else {
302- return ;
303- } ;
295+ fn check_mul_add ( cx : & LateContext < ' _ , ' _ > , expr : & Expr < ' _ > ) {
296+ if let ExprKind :: Binary (
297+ Spanned {
298+ node : BinOpKind :: Add , ..
299+ } ,
300+ lhs,
301+ rhs,
302+ ) = & expr. kind
303+ {
304+ let ( recv, arg1, arg2) = if let Some ( ( inner_lhs, inner_rhs) ) = is_float_mul_expr ( cx, lhs) {
305+ ( inner_lhs, inner_rhs, rhs)
306+ } else if let Some ( ( inner_lhs, inner_rhs) ) = is_float_mul_expr ( cx, rhs) {
307+ ( inner_lhs, inner_rhs, lhs)
308+ } else {
309+ return ;
310+ } ;
304311
305- span_lint_and_sugg(
306- cx,
307- SUBOPTIMAL_FLOPS ,
308- expr. span,
309- "multiply and add expressions can be calculated more efficiently and accurately" ,
310- "consider using" ,
311- format!(
312- "{}.mul_add({}, {})" ,
313- prepare_receiver_sugg( cx, recv) ,
314- Sugg :: hir( cx, arg1, ".." ) ,
315- Sugg :: hir( cx, arg2, ".." ) ,
316- ) ,
317- Applicability :: MachineApplicable ,
318- ) ;
319- }
312+ span_lint_and_sugg (
313+ cx,
314+ SUBOPTIMAL_FLOPS ,
315+ expr. span ,
316+ "multiply and add expressions can be calculated more efficiently and accurately" ,
317+ "consider using" ,
318+ format ! (
319+ "{}.mul_add({}, {})" ,
320+ prepare_receiver_sugg( cx, recv) ,
321+ Sugg :: hir( cx, arg1, ".." ) ,
322+ Sugg :: hir( cx, arg2, ".." ) ,
323+ ) ,
324+ Applicability :: MachineApplicable ,
325+ ) ;
320326 }
321327}
322328
@@ -335,7 +341,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for FloatingPointArithmetic {
335341 }
336342 } else {
337343 check_expm1 ( cx, expr) ;
338- check_fma ( cx, expr) ;
344+ check_mul_add ( cx, expr) ;
339345 }
340346 }
341347}
0 commit comments