@@ -9,6 +9,8 @@ use rustc_errors::Applicability;
9
9
use rustc_hir:: { BinOpKind , Expr , ExprKind , UnOp } ;
10
10
use rustc_lint:: { LateContext , LateLintPass } ;
11
11
use rustc_session:: { declare_lint_pass, declare_tool_lint} ;
12
+ use rustc_span:: source_map:: Spanned ;
13
+
12
14
use std:: f32:: consts as f32_consts;
13
15
use std:: f64:: consts as f64_consts;
14
16
use sugg:: { format_numeric_literal, Sugg } ;
@@ -138,26 +140,29 @@ fn check_log_base(cx: &LateContext<'_, '_>, expr: &Expr<'_>, args: &[Expr<'_>])
138
140
// TODO: Lint expressions of the form `(x + y).ln()` where y > 1 and
139
141
// suggest usage of `(x + (y - 1)).ln_1p()` instead
140
142
fn 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
+ } ;
150
156
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
+ ) ;
161
166
}
162
167
}
163
168
@@ -249,8 +254,7 @@ fn check_powf(cx: &LateContext<'_, '_>, expr: &Expr<'_>, args: &[Expr<'_>]) {
249
254
// and suggest usage of `x.exp_m1() - (y - 1)` instead
250
255
fn check_expm1 ( cx : & LateContext < ' _ , ' _ > , expr : & Expr < ' _ > ) {
251
256
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;
254
258
if cx. tables. expr_ty( lhs) . is_floating_point( ) ;
255
259
if let Some ( ( value, _) ) = constant( cx, cx. tables, rhs) ;
256
260
if F32 ( 1.0 ) == value || F64 ( 1.0 ) == value;
@@ -276,8 +280,7 @@ fn check_expm1(cx: &LateContext<'_, '_>, expr: &Expr<'_>) {
276
280
277
281
fn is_float_mul_expr < ' a > ( cx : & LateContext < ' _ , ' _ > , expr : & ' a Expr < ' a > ) -> Option < ( & ' a Expr < ' a > , & ' a Expr < ' a > ) > {
278
282
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;
281
284
if cx. tables. expr_ty( lhs) . is_floating_point( ) ;
282
285
if cx. tables. expr_ty( rhs) . is_floating_point( ) ;
283
286
then {
@@ -289,34 +292,37 @@ fn is_float_mul_expr<'a>(cx: &LateContext<'_, '_>, expr: &'a Expr<'a>) -> Option
289
292
}
290
293
291
294
// 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
+ } ;
304
311
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
+ ) ;
320
326
}
321
327
}
322
328
@@ -335,7 +341,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for FloatingPointArithmetic {
335
341
}
336
342
} else {
337
343
check_expm1 ( cx, expr) ;
338
- check_fma ( cx, expr) ;
344
+ check_mul_add ( cx, expr) ;
339
345
}
340
346
}
341
347
}
0 commit comments