@@ -420,103 +420,84 @@ fn is_zero(expr: &Expr<'_>) -> bool {
420
420
}
421
421
}
422
422
423
- fn check_custom_abs ( cx : & LateContext < ' _ , ' _ > , expr : & Expr < ' _ > ) {
424
- if let Some ( ( cond, body, Some ( else_body) ) ) = higher:: if_block ( & expr) {
423
+ /// If the expressions are not opposites, return None
424
+ /// Otherwise, return true if expr2 = -expr1, false if expr1 = -expr2 and return the positive
425
+ /// expression
426
+ fn are_opposites < ' a > (
427
+ cx : & LateContext < ' _ , ' _ > ,
428
+ expr1 : & ' a Expr < ' a > ,
429
+ expr2 : & ' a Expr < ' a > ,
430
+ ) -> Option < ( bool , & ' a Expr < ' a > ) > {
431
+ if let ExprKind :: Block (
432
+ Block {
433
+ stmts : [ ] ,
434
+ expr : Some ( expr1_inner) ,
435
+ ..
436
+ } ,
437
+ _,
438
+ ) = & expr1. kind
439
+ {
425
440
if let ExprKind :: Block (
426
441
Block {
427
442
stmts : [ ] ,
428
- expr :
429
- Some ( Expr {
430
- kind : ExprKind :: Unary ( UnOp :: UnNeg , else_expr) ,
431
- ..
432
- } ) ,
443
+ expr : Some ( expr2_inner) ,
433
444
..
434
445
} ,
435
446
_,
436
- ) = else_body . kind
447
+ ) = & expr2 . kind
437
448
{
438
- if let ExprKind :: Block (
439
- Block {
440
- stmts : [ ] ,
441
- expr : Some ( body) ,
442
- ..
443
- } ,
444
- _,
445
- ) = & body. kind
446
- {
447
- if are_exprs_equal ( cx, else_expr, body) {
448
- if is_testing_positive ( cx, cond, body) {
449
- span_lint_and_sugg (
450
- cx,
451
- SUBOPTIMAL_FLOPS ,
452
- expr. span ,
453
- "This looks like you've implemented your own absolute value function" ,
454
- "try" ,
455
- format ! ( "{}.abs()" , Sugg :: hir( cx, body, ".." ) ) ,
456
- Applicability :: MachineApplicable ,
457
- ) ;
458
- } else if is_testing_negative ( cx, cond, body) {
459
- span_lint_and_sugg (
460
- cx,
461
- SUBOPTIMAL_FLOPS ,
462
- expr. span ,
463
- "This looks like you've implemented your own negative absolute value function" ,
464
- "try" ,
465
- format ! ( "-{}.abs()" , Sugg :: hir( cx, body, ".." ) ) ,
466
- Applicability :: MachineApplicable ,
467
- ) ;
468
- }
449
+ if let ExprKind :: Unary ( UnOp :: UnNeg , expr1_neg) = & expr1_inner. kind {
450
+ if are_exprs_equal ( cx, expr1_neg, expr2_inner) {
451
+ return Some ( ( false , expr2_inner) ) ;
469
452
}
470
453
}
471
- }
472
- if let ExprKind :: Block (
473
- Block {
474
- stmts : [ ] ,
475
- expr :
476
- Some ( Expr {
477
- kind : ExprKind :: Unary ( UnOp :: UnNeg , else_expr) ,
478
- ..
479
- } ) ,
480
- ..
481
- } ,
482
- _,
483
- ) = & body. kind
484
- {
485
- if let ExprKind :: Block (
486
- Block {
487
- stmts : [ ] ,
488
- expr : Some ( body) ,
489
- ..
490
- } ,
491
- _,
492
- ) = & else_body. kind
493
- {
494
- if are_exprs_equal ( cx, else_expr, body) {
495
- if is_testing_negative ( cx, cond, body) {
496
- span_lint_and_sugg (
497
- cx,
498
- SUBOPTIMAL_FLOPS ,
499
- expr. span ,
500
- "This looks like you've implemented your own absolute value function" ,
501
- "try" ,
502
- format ! ( "{}.abs()" , Sugg :: hir( cx, body, ".." ) ) ,
503
- Applicability :: MachineApplicable ,
504
- ) ;
505
- } else if is_testing_positive ( cx, cond, body) {
506
- span_lint_and_sugg (
507
- cx,
508
- SUBOPTIMAL_FLOPS ,
509
- expr. span ,
510
- "This looks like you've implemented your own negative absolute value function" ,
511
- "try" ,
512
- format ! ( "-{}.abs()" , Sugg :: hir( cx, body, ".." ) ) ,
513
- Applicability :: MachineApplicable ,
514
- ) ;
515
- }
454
+ if let ExprKind :: Unary ( UnOp :: UnNeg , expr2_neg) = & expr2_inner. kind {
455
+ if are_exprs_equal ( cx, expr1_inner, expr2_neg) {
456
+ return Some ( ( true , expr1_inner) ) ;
516
457
}
517
458
}
518
459
}
519
460
}
461
+ None
462
+ }
463
+
464
+ fn check_custom_abs ( cx : & LateContext < ' _ , ' _ > , expr : & Expr < ' _ > ) {
465
+ if let Some ( ( cond, body, Some ( else_body) ) ) = higher:: if_block ( & expr) {
466
+ if let Some ( ( expr1_pos, body) ) = are_opposites ( cx, body, else_body) {
467
+ let pos_abs_sugg = (
468
+ "This looks like you've implemented your own absolute value function" ,
469
+ format ! ( "{}.abs()" , Sugg :: hir( cx, body, ".." ) ) ,
470
+ ) ;
471
+ let neg_abs_sugg = (
472
+ "This looks like you've implemented your own negative absolute value function" ,
473
+ format ! ( "-{}.abs()" , Sugg :: hir( cx, body, ".." ) ) ,
474
+ ) ;
475
+ let sugg = if is_testing_positive ( cx, cond, body) {
476
+ if expr1_pos {
477
+ pos_abs_sugg
478
+ } else {
479
+ neg_abs_sugg
480
+ }
481
+ } else if is_testing_negative ( cx, cond, body) {
482
+ if expr1_pos {
483
+ neg_abs_sugg
484
+ } else {
485
+ pos_abs_sugg
486
+ }
487
+ } else {
488
+ return ;
489
+ } ;
490
+ span_lint_and_sugg (
491
+ cx,
492
+ SUBOPTIMAL_FLOPS ,
493
+ expr. span ,
494
+ sugg. 0 ,
495
+ "try" ,
496
+ sugg. 1 ,
497
+ Applicability :: MachineApplicable ,
498
+ ) ;
499
+ }
500
+ }
520
501
}
521
502
522
503
impl < ' a , ' tcx > LateLintPass < ' a , ' tcx > for FloatingPointArithmetic {
0 commit comments