@@ -369,26 +369,28 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MiscLints {
369369 return ;
370370 }
371371 }
372- let ( lint , msg ) = if is_named_constant ( cx, left) || is_named_constant ( cx, right) {
373- ( FLOAT_CMP_CONST , "strict comparison of `f32` or `f64` constant" )
374- } else {
375- ( FLOAT_CMP , "strict comparison of `f32` or `f64`" )
376- } ;
372+ let is_comparing_arrays = is_array ( cx, left) || is_array ( cx, right) ;
373+ let ( lint , msg ) = get_lint_and_message (
374+ is_named_constant ( cx , left ) || is_named_constant ( cx , right ) ,
375+ is_comparing_arrays ,
376+ ) ;
377377 span_lint_and_then ( cx, lint, expr. span , msg, |db| {
378378 let lhs = Sugg :: hir ( cx, left, ".." ) ;
379379 let rhs = Sugg :: hir ( cx, right, ".." ) ;
380380
381- db. span_suggestion (
382- expr. span ,
383- "consider comparing them within some error" ,
384- format ! (
385- "({}).abs() {} error" ,
386- lhs - rhs,
387- if op == BinOpKind :: Eq { '<' } else { '>' }
388- ) ,
389- Applicability :: HasPlaceholders , // snippet
390- ) ;
391- db. span_note ( expr. span , "`f32::EPSILON` and `f64::EPSILON` are available." ) ;
381+ if !is_comparing_arrays {
382+ db. span_suggestion (
383+ expr. span ,
384+ "consider comparing them within some error" ,
385+ format ! (
386+ "({}).abs() {} error" ,
387+ lhs - rhs,
388+ if op == BinOpKind :: Eq { '<' } else { '>' }
389+ ) ,
390+ Applicability :: HasPlaceholders , // snippet
391+ ) ;
392+ }
393+ db. note ( "`f32::EPSILON` and `f64::EPSILON` are available for the `error`" ) ;
392394 } ) ;
393395 } else if op == BinOpKind :: Rem && is_integer_const ( cx, right, 1 ) {
394396 span_lint ( cx, MODULO_ONE , expr. span , "any number modulo 1 will be 0" ) ;
@@ -440,6 +442,31 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MiscLints {
440442 }
441443}
442444
445+ fn get_lint_and_message (
446+ is_comparing_constants : bool ,
447+ is_comparing_arrays : bool ,
448+ ) -> ( & ' static rustc_lint:: Lint , & ' static str ) {
449+ if is_comparing_constants {
450+ (
451+ FLOAT_CMP_CONST ,
452+ if is_comparing_arrays {
453+ "strict comparison of `f32` or `f64` constant arrays"
454+ } else {
455+ "strict comparison of `f32` or `f64` constant"
456+ } ,
457+ )
458+ } else {
459+ (
460+ FLOAT_CMP ,
461+ if is_comparing_arrays {
462+ "strict comparison of `f32` or `f64` arrays"
463+ } else {
464+ "strict comparison of `f32` or `f64`"
465+ } ,
466+ )
467+ }
468+ }
469+
443470fn check_nan ( cx : & LateContext < ' _ , ' _ > , expr : & Expr < ' _ > , cmp_expr : & Expr < ' _ > ) {
444471 if_chain ! {
445472 if !in_constant( cx, cmp_expr. hir_id) ;
@@ -475,6 +502,11 @@ fn is_allowed<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr<'_>) -> boo
475502 match constant ( cx, cx. tables , expr) {
476503 Some ( ( Constant :: F32 ( f) , _) ) => f == 0.0 || f. is_infinite ( ) ,
477504 Some ( ( Constant :: F64 ( f) , _) ) => f == 0.0 || f. is_infinite ( ) ,
505+ Some ( ( Constant :: Vec ( vec) , _) ) => vec. iter ( ) . all ( |f| match f {
506+ Constant :: F32 ( f) => * f == 0.0 || ( * f) . is_infinite ( ) ,
507+ Constant :: F64 ( f) => * f == 0.0 || ( * f) . is_infinite ( ) ,
508+ _ => false ,
509+ } ) ,
478510 _ => false ,
479511 }
480512}
@@ -499,7 +531,17 @@ fn is_signum(cx: &LateContext<'_, '_>, expr: &Expr<'_>) -> bool {
499531}
500532
501533fn is_float ( cx : & LateContext < ' _ , ' _ > , expr : & Expr < ' _ > ) -> bool {
502- matches ! ( walk_ptrs_ty( cx. tables. expr_ty( expr) ) . kind, ty:: Float ( _) )
534+ let value = & walk_ptrs_ty ( cx. tables . expr_ty ( expr) ) . kind ;
535+
536+ if let ty:: Array ( arr_ty, _) = value {
537+ return matches ! ( arr_ty. kind, ty:: Float ( _) ) ;
538+ } ;
539+
540+ matches ! ( value, ty:: Float ( _) )
541+ }
542+
543+ fn is_array ( cx : & LateContext < ' _ , ' _ > , expr : & Expr < ' _ > ) -> bool {
544+ matches ! ( & walk_ptrs_ty( cx. tables. expr_ty( expr) ) . kind, ty:: Array ( _, _) )
503545}
504546
505547fn check_to_owned ( cx : & LateContext < ' _ , ' _ > , expr : & Expr < ' _ > , other : & Expr < ' _ > ) {
0 commit comments