@@ -381,73 +381,8 @@ impl<'tcx> LateLintPass<'tcx> for MiscLints {
381381 return ;
382382 } ,
383383 ExprKind :: Binary ( ref cmp, ref left, ref right) => {
384- let op = cmp. node ;
385- if op. is_comparison ( ) {
386- check_nan ( cx, left, expr) ;
387- check_nan ( cx, right, expr) ;
388- check_to_owned ( cx, left, right, true ) ;
389- check_to_owned ( cx, right, left, false ) ;
390- }
391- if ( op == BinOpKind :: Eq || op == BinOpKind :: Ne ) && ( is_float ( cx, left) || is_float ( cx, right) ) {
392- if is_allowed ( cx, left) || is_allowed ( cx, right) {
393- return ;
394- }
395-
396- // Allow comparing the results of signum()
397- if is_signum ( cx, left) && is_signum ( cx, right) {
398- return ;
399- }
400-
401- if let Some ( name) = get_item_name ( cx, expr) {
402- let name = name. as_str ( ) ;
403- if name == "eq"
404- || name == "ne"
405- || name == "is_nan"
406- || name. starts_with ( "eq_" )
407- || name. ends_with ( "_eq" )
408- {
409- return ;
410- }
411- }
412- let is_comparing_arrays = is_array ( cx, left) || is_array ( cx, right) ;
413- let ( lint, msg) = get_lint_and_message (
414- is_named_constant ( cx, left) || is_named_constant ( cx, right) ,
415- is_comparing_arrays,
416- ) ;
417- span_lint_and_then ( cx, lint, expr. span , msg, |diag| {
418- let lhs = Sugg :: hir ( cx, left, ".." ) ;
419- let rhs = Sugg :: hir ( cx, right, ".." ) ;
420-
421- if !is_comparing_arrays {
422- diag. span_suggestion (
423- expr. span ,
424- "consider comparing them within some margin of error" ,
425- format ! (
426- "({}).abs() {} error_margin" ,
427- lhs - rhs,
428- if op == BinOpKind :: Eq { '<' } else { '>' }
429- ) ,
430- Applicability :: HasPlaceholders , // snippet
431- ) ;
432- }
433- diag. note ( "`f32::EPSILON` and `f64::EPSILON` are available for the `error_margin`" ) ;
434- } ) ;
435- } else if op == BinOpKind :: Rem {
436- if is_integer_const ( cx, right, 1 ) {
437- span_lint ( cx, MODULO_ONE , expr. span , "any number modulo 1 will be 0" ) ;
438- }
439-
440- if let ty:: Int ( ity) = cx. typeck_results ( ) . expr_ty ( right) . kind ( ) {
441- if is_integer_const ( cx, right, unsext ( cx. tcx , -1 , * ity) ) {
442- span_lint (
443- cx,
444- MODULO_ONE ,
445- expr. span ,
446- "any number modulo -1 will panic/overflow or result in 0" ,
447- ) ;
448- }
449- } ;
450- }
384+ check_binary ( cx, expr, cmp, left, right) ;
385+ return ;
451386 } ,
452387 _ => { } ,
453388 }
@@ -760,3 +695,74 @@ fn check_cast(cx: &LateContext<'_>, span: Span, e: &Expr<'_>, ty: &hir::Ty<'_>)
760695 }
761696 }
762697}
698+
699+ fn check_binary (
700+ cx : & LateContext < ' a > ,
701+ expr : & Expr < ' _ > ,
702+ cmp : & rustc_span:: source_map:: Spanned < rustc_hir:: BinOpKind > ,
703+ left : & ' a Expr < ' _ > ,
704+ right : & ' a Expr < ' _ > ,
705+ ) {
706+ let op = cmp. node ;
707+ if op. is_comparison ( ) {
708+ check_nan ( cx, left, expr) ;
709+ check_nan ( cx, right, expr) ;
710+ check_to_owned ( cx, left, right, true ) ;
711+ check_to_owned ( cx, right, left, false ) ;
712+ }
713+ if ( op == BinOpKind :: Eq || op == BinOpKind :: Ne ) && ( is_float ( cx, left) || is_float ( cx, right) ) {
714+ if is_allowed ( cx, left) || is_allowed ( cx, right) {
715+ return ;
716+ }
717+
718+ // Allow comparing the results of signum()
719+ if is_signum ( cx, left) && is_signum ( cx, right) {
720+ return ;
721+ }
722+
723+ if let Some ( name) = get_item_name ( cx, expr) {
724+ let name = name. as_str ( ) ;
725+ if name == "eq" || name == "ne" || name == "is_nan" || name. starts_with ( "eq_" ) || name. ends_with ( "_eq" ) {
726+ return ;
727+ }
728+ }
729+ let is_comparing_arrays = is_array ( cx, left) || is_array ( cx, right) ;
730+ let ( lint, msg) = get_lint_and_message (
731+ is_named_constant ( cx, left) || is_named_constant ( cx, right) ,
732+ is_comparing_arrays,
733+ ) ;
734+ span_lint_and_then ( cx, lint, expr. span , msg, |diag| {
735+ let lhs = Sugg :: hir ( cx, left, ".." ) ;
736+ let rhs = Sugg :: hir ( cx, right, ".." ) ;
737+
738+ if !is_comparing_arrays {
739+ diag. span_suggestion (
740+ expr. span ,
741+ "consider comparing them within some margin of error" ,
742+ format ! (
743+ "({}).abs() {} error_margin" ,
744+ lhs - rhs,
745+ if op == BinOpKind :: Eq { '<' } else { '>' }
746+ ) ,
747+ Applicability :: HasPlaceholders , // snippet
748+ ) ;
749+ }
750+ diag. note ( "`f32::EPSILON` and `f64::EPSILON` are available for the `error_margin`" ) ;
751+ } ) ;
752+ } else if op == BinOpKind :: Rem {
753+ if is_integer_const ( cx, right, 1 ) {
754+ span_lint ( cx, MODULO_ONE , expr. span , "any number modulo 1 will be 0" ) ;
755+ }
756+
757+ if let ty:: Int ( ity) = cx. typeck_results ( ) . expr_ty ( right) . kind ( ) {
758+ if is_integer_const ( cx, right, unsext ( cx. tcx , -1 , * ity) ) {
759+ span_lint (
760+ cx,
761+ MODULO_ONE ,
762+ expr. span ,
763+ "any number modulo -1 will panic/overflow or result in 0" ,
764+ ) ;
765+ }
766+ } ;
767+ }
768+ }
0 commit comments