about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2021-07-13 14:31:02 +0000
committerbors <bors@rust-lang.org>2021-07-13 14:31:02 +0000
commit8131445e536869b4b73b07d1be1b2e03f7493898 (patch)
treeeaf87cfe60eed75f6872ec34d3082911de7b1c72
parentbf4512ef57aaaebcf537af47380026d40238685b (diff)
parent25e4c7d73fd4c929208edf151c827f6c97318374 (diff)
downloadrust-8131445e536869b4b73b07d1be1b2e03f7493898.tar.gz
rust-8131445e536869b4b73b07d1be1b2e03f7493898.zip
Auto merge of #7446 - Y-Nak:fix-7445, r=xFrednet,flip1995
`default_numeric_fallback`: Fix FP with floating literal

Fix #7445

changelog: `default_numeric_fallback`: Fix FP with floating literal
-rw-r--r--clippy_lints/src/default_numeric_fallback.rs26
-rw-r--r--clippy_utils/src/numeric_literal.rs3
-rw-r--r--tests/ui/default_numeric_fallback_f64.fixed174
-rw-r--r--tests/ui/default_numeric_fallback_f64.rs174
-rw-r--r--tests/ui/default_numeric_fallback_f64.stderr147
-rw-r--r--tests/ui/default_numeric_fallback_i32.fixed173
-rw-r--r--tests/ui/default_numeric_fallback_i32.rs (renamed from tests/ui/default_numeric_fallback.rs)24
-rw-r--r--tests/ui/default_numeric_fallback_i32.stderr (renamed from tests/ui/default_numeric_fallback.stderr)60
8 files changed, 738 insertions, 43 deletions
diff --git a/clippy_lints/src/default_numeric_fallback.rs b/clippy_lints/src/default_numeric_fallback.rs
index a125376bffa..e719a1b0abf 100644
--- a/clippy_lints/src/default_numeric_fallback.rs
+++ b/clippy_lints/src/default_numeric_fallback.rs
@@ -1,5 +1,6 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
-use clippy_utils::source::snippet;
+use clippy_utils::numeric_literal;
+use clippy_utils::source::snippet_opt;
 use if_chain::if_chain;
 use rustc_ast::ast::{LitFloatType, LitIntType, LitKind};
 use rustc_errors::Applicability;
@@ -78,16 +79,25 @@ impl<'a, 'tcx> NumericFallbackVisitor<'a, 'tcx> {
                 if let Some(ty_bound) = self.ty_bounds.last();
                 if matches!(lit.node,
                             LitKind::Int(_, LitIntType::Unsuffixed) | LitKind::Float(_, LitFloatType::Unsuffixed));
-                if !ty_bound.is_integral();
+                if !ty_bound.is_numeric();
                 then {
-                    let suffix = match lit_ty.kind() {
-                        ty::Int(IntTy::I32) => "i32",
-                        ty::Float(FloatTy::F64) => "f64",
+                    let (suffix, is_float) = match lit_ty.kind() {
+                        ty::Int(IntTy::I32) => ("i32", false),
+                        ty::Float(FloatTy::F64) => ("f64", true),
                         // Default numeric fallback never results in other types.
                         _ => return,
                     };
 
-                    let sugg = format!("{}_{}", snippet(self.cx, lit.span, ""), suffix);
+                    let src = if let Some(src) = snippet_opt(self.cx, lit.span) {
+                        src
+                    } else {
+                        match lit.node {
+                            LitKind::Int(src, _) => format!("{}", src),
+                            LitKind::Float(src, _) => format!("{}", src),
+                            _ => return,
+                        }
+                    };
+                    let sugg = numeric_literal::format(&src, Some(suffix), is_float);
                     span_lint_and_sugg(
                         self.cx,
                         DEFAULT_NUMERIC_FALLBACK,
@@ -219,10 +229,10 @@ enum TyBound<'tcx> {
 }
 
 impl<'tcx> TyBound<'tcx> {
-    fn is_integral(self) -> bool {
+    fn is_numeric(self) -> bool {
         match self {
             TyBound::Any => true,
-            TyBound::Ty(t) => t.is_integral(),
+            TyBound::Ty(t) => t.is_numeric(),
             TyBound::Nothing => false,
         }
     }
diff --git a/clippy_utils/src/numeric_literal.rs b/clippy_utils/src/numeric_literal.rs
index 546706d51d7..4a28c7dd9a0 100644
--- a/clippy_utils/src/numeric_literal.rs
+++ b/clippy_utils/src/numeric_literal.rs
@@ -162,6 +162,9 @@ impl<'a> NumericLiteral<'a> {
         }
 
         if let Some(suffix) = self.suffix {
+            if output.ends_with('.') {
+                output.push('0');
+            }
             output.push('_');
             output.push_str(suffix);
         }
diff --git a/tests/ui/default_numeric_fallback_f64.fixed b/tests/ui/default_numeric_fallback_f64.fixed
new file mode 100644
index 00000000000..1b0e7544e79
--- /dev/null
+++ b/tests/ui/default_numeric_fallback_f64.fixed
@@ -0,0 +1,174 @@
+// run-rustfix
+// aux-build:macro_rules.rs
+
+#![warn(clippy::default_numeric_fallback)]
+#![allow(unused)]
+#![allow(clippy::never_loop)]
+#![allow(clippy::no_effect)]
+#![allow(clippy::unnecessary_operation)]
+#![allow(clippy::branches_sharing_code)]
+#![allow(clippy::match_single_binding)]
+
+#[macro_use]
+extern crate macro_rules;
+
+mod basic_expr {
+    fn test() {
+        // Should lint unsuffixed literals typed `f64`.
+        let x = 0.12_f64;
+        let x = [1.0_f64, 2.0_f64, 3.0_f64];
+        let x = if true { (1.0_f64, 2.0_f64) } else { (3.0_f64, 4.0_f64) };
+        let x = match 1.0_f64 {
+            _ => 1.0_f64,
+        };
+
+        // Should NOT lint suffixed literals.
+        let x = 0.12_f64;
+
+        // Should NOT lint literals in init expr if `Local` has a type annotation.
+        let x: f64 = 0.1;
+        let x: [f64; 3] = [1., 2., 3.];
+        let x: (f64, f64) = if true { (1., 2.) } else { (3., 4.) };
+        let x: _ = 1.;
+    }
+}
+
+mod nested_local {
+    fn test() {
+        let x: _ = {
+            // Should lint this because this literal is not bound to any types.
+            let y = 1.0_f64;
+
+            // Should NOT lint this because this literal is bound to `_` of outer `Local`.
+            1.
+        };
+
+        let x: _ = if true {
+            // Should lint this because this literal is not bound to any types.
+            let y = 1.0_f64;
+
+            // Should NOT lint this because this literal is bound to `_` of outer `Local`.
+            1.
+        } else {
+            // Should lint this because this literal is not bound to any types.
+            let y = 1.0_f64;
+
+            // Should NOT lint this because this literal is bound to `_` of outer `Local`.
+            2.
+        };
+    }
+}
+
+mod function_def {
+    fn ret_f64() -> f64 {
+        // Even though the output type is specified,
+        // this unsuffixed literal is linted to reduce heuristics and keep codebase simple.
+        1.0_f64
+    }
+
+    fn test() {
+        // Should lint this because return type is inferred to `f64` and NOT bound to a concrete
+        // type.
+        let f = || -> _ { 1.0_f64 };
+
+        // Even though the output type is specified,
+        // this unsuffixed literal is linted to reduce heuristics and keep codebase simple.
+        let f = || -> f64 { 1.0_f64 };
+    }
+}
+
+mod function_calls {
+    fn concrete_arg(f: f64) {}
+
+    fn generic_arg<T>(t: T) {}
+
+    fn test() {
+        // Should NOT lint this because the argument type is bound to a concrete type.
+        concrete_arg(1.);
+
+        // Should lint this because the argument type is inferred to `f64` and NOT bound to a concrete type.
+        generic_arg(1.0_f64);
+
+        // Should lint this because the argument type is inferred to `f64` and NOT bound to a concrete type.
+        let x: _ = generic_arg(1.0_f64);
+    }
+}
+
+mod struct_ctor {
+    struct ConcreteStruct {
+        x: f64,
+    }
+
+    struct GenericStruct<T> {
+        x: T,
+    }
+
+    fn test() {
+        // Should NOT lint this because the field type is bound to a concrete type.
+        ConcreteStruct { x: 1. };
+
+        // Should lint this because the field type is inferred to `f64` and NOT bound to a concrete type.
+        GenericStruct { x: 1.0_f64 };
+
+        // Should lint this because the field type is inferred to `f64` and NOT bound to a concrete type.
+        let _ = GenericStruct { x: 1.0_f64 };
+    }
+}
+
+mod enum_ctor {
+    enum ConcreteEnum {
+        X(f64),
+    }
+
+    enum GenericEnum<T> {
+        X(T),
+    }
+
+    fn test() {
+        // Should NOT lint this because the field type is bound to a concrete type.
+        ConcreteEnum::X(1.);
+
+        // Should lint this because the field type is inferred to `f64` and NOT bound to a concrete type.
+        GenericEnum::X(1.0_f64);
+    }
+}
+
+mod method_calls {
+    struct StructForMethodCallTest {}
+
+    impl StructForMethodCallTest {
+        fn concrete_arg(&self, f: f64) {}
+
+        fn generic_arg<T>(&self, t: T) {}
+    }
+
+    fn test() {
+        let s = StructForMethodCallTest {};
+
+        // Should NOT lint this because the argument type is bound to a concrete type.
+        s.concrete_arg(1.);
+
+        // Should lint this because the argument type is bound to a concrete type.
+        s.generic_arg(1.0_f64);
+    }
+}
+
+mod in_macro {
+    macro_rules! internal_macro {
+        () => {
+            let x = 22.0_f64;
+        };
+    }
+
+    // Should lint in internal macro.
+    fn internal() {
+        internal_macro!();
+    }
+
+    // Should NOT lint in external macro.
+    fn external() {
+        default_numeric_fallback!();
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/default_numeric_fallback_f64.rs b/tests/ui/default_numeric_fallback_f64.rs
new file mode 100644
index 00000000000..e9687777bbd
--- /dev/null
+++ b/tests/ui/default_numeric_fallback_f64.rs
@@ -0,0 +1,174 @@
+// run-rustfix
+// aux-build:macro_rules.rs
+
+#![warn(clippy::default_numeric_fallback)]
+#![allow(unused)]
+#![allow(clippy::never_loop)]
+#![allow(clippy::no_effect)]
+#![allow(clippy::unnecessary_operation)]
+#![allow(clippy::branches_sharing_code)]
+#![allow(clippy::match_single_binding)]
+
+#[macro_use]
+extern crate macro_rules;
+
+mod basic_expr {
+    fn test() {
+        // Should lint unsuffixed literals typed `f64`.
+        let x = 0.12;
+        let x = [1., 2., 3.];
+        let x = if true { (1., 2.) } else { (3., 4.) };
+        let x = match 1. {
+            _ => 1.,
+        };
+
+        // Should NOT lint suffixed literals.
+        let x = 0.12_f64;
+
+        // Should NOT lint literals in init expr if `Local` has a type annotation.
+        let x: f64 = 0.1;
+        let x: [f64; 3] = [1., 2., 3.];
+        let x: (f64, f64) = if true { (1., 2.) } else { (3., 4.) };
+        let x: _ = 1.;
+    }
+}
+
+mod nested_local {
+    fn test() {
+        let x: _ = {
+            // Should lint this because this literal is not bound to any types.
+            let y = 1.;
+
+            // Should NOT lint this because this literal is bound to `_` of outer `Local`.
+            1.
+        };
+
+        let x: _ = if true {
+            // Should lint this because this literal is not bound to any types.
+            let y = 1.;
+
+            // Should NOT lint this because this literal is bound to `_` of outer `Local`.
+            1.
+        } else {
+            // Should lint this because this literal is not bound to any types.
+            let y = 1.;
+
+            // Should NOT lint this because this literal is bound to `_` of outer `Local`.
+            2.
+        };
+    }
+}
+
+mod function_def {
+    fn ret_f64() -> f64 {
+        // Even though the output type is specified,
+        // this unsuffixed literal is linted to reduce heuristics and keep codebase simple.
+        1.
+    }
+
+    fn test() {
+        // Should lint this because return type is inferred to `f64` and NOT bound to a concrete
+        // type.
+        let f = || -> _ { 1. };
+
+        // Even though the output type is specified,
+        // this unsuffixed literal is linted to reduce heuristics and keep codebase simple.
+        let f = || -> f64 { 1. };
+    }
+}
+
+mod function_calls {
+    fn concrete_arg(f: f64) {}
+
+    fn generic_arg<T>(t: T) {}
+
+    fn test() {
+        // Should NOT lint this because the argument type is bound to a concrete type.
+        concrete_arg(1.);
+
+        // Should lint this because the argument type is inferred to `f64` and NOT bound to a concrete type.
+        generic_arg(1.);
+
+        // Should lint this because the argument type is inferred to `f64` and NOT bound to a concrete type.
+        let x: _ = generic_arg(1.);
+    }
+}
+
+mod struct_ctor {
+    struct ConcreteStruct {
+        x: f64,
+    }
+
+    struct GenericStruct<T> {
+        x: T,
+    }
+
+    fn test() {
+        // Should NOT lint this because the field type is bound to a concrete type.
+        ConcreteStruct { x: 1. };
+
+        // Should lint this because the field type is inferred to `f64` and NOT bound to a concrete type.
+        GenericStruct { x: 1. };
+
+        // Should lint this because the field type is inferred to `f64` and NOT bound to a concrete type.
+        let _ = GenericStruct { x: 1. };
+    }
+}
+
+mod enum_ctor {
+    enum ConcreteEnum {
+        X(f64),
+    }
+
+    enum GenericEnum<T> {
+        X(T),
+    }
+
+    fn test() {
+        // Should NOT lint this because the field type is bound to a concrete type.
+        ConcreteEnum::X(1.);
+
+        // Should lint this because the field type is inferred to `f64` and NOT bound to a concrete type.
+        GenericEnum::X(1.);
+    }
+}
+
+mod method_calls {
+    struct StructForMethodCallTest {}
+
+    impl StructForMethodCallTest {
+        fn concrete_arg(&self, f: f64) {}
+
+        fn generic_arg<T>(&self, t: T) {}
+    }
+
+    fn test() {
+        let s = StructForMethodCallTest {};
+
+        // Should NOT lint this because the argument type is bound to a concrete type.
+        s.concrete_arg(1.);
+
+        // Should lint this because the argument type is bound to a concrete type.
+        s.generic_arg(1.);
+    }
+}
+
+mod in_macro {
+    macro_rules! internal_macro {
+        () => {
+            let x = 22.;
+        };
+    }
+
+    // Should lint in internal macro.
+    fn internal() {
+        internal_macro!();
+    }
+
+    // Should NOT lint in external macro.
+    fn external() {
+        default_numeric_fallback!();
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/default_numeric_fallback_f64.stderr b/tests/ui/default_numeric_fallback_f64.stderr
new file mode 100644
index 00000000000..961c7cb57c5
--- /dev/null
+++ b/tests/ui/default_numeric_fallback_f64.stderr
@@ -0,0 +1,147 @@
+error: default numeric fallback might occur
+  --> $DIR/default_numeric_fallback_f64.rs:18:17
+   |
+LL |         let x = 0.12;
+   |                 ^^^^ help: consider adding suffix: `0.12_f64`
+   |
+   = note: `-D clippy::default-numeric-fallback` implied by `-D warnings`
+
+error: default numeric fallback might occur
+  --> $DIR/default_numeric_fallback_f64.rs:19:18
+   |
+LL |         let x = [1., 2., 3.];
+   |                  ^^ help: consider adding suffix: `1.0_f64`
+
+error: default numeric fallback might occur
+  --> $DIR/default_numeric_fallback_f64.rs:19:22
+   |
+LL |         let x = [1., 2., 3.];
+   |                      ^^ help: consider adding suffix: `2.0_f64`
+
+error: default numeric fallback might occur
+  --> $DIR/default_numeric_fallback_f64.rs:19:26
+   |
+LL |         let x = [1., 2., 3.];
+   |                          ^^ help: consider adding suffix: `3.0_f64`
+
+error: default numeric fallback might occur
+  --> $DIR/default_numeric_fallback_f64.rs:20:28
+   |
+LL |         let x = if true { (1., 2.) } else { (3., 4.) };
+   |                            ^^ help: consider adding suffix: `1.0_f64`
+
+error: default numeric fallback might occur
+  --> $DIR/default_numeric_fallback_f64.rs:20:32
+   |
+LL |         let x = if true { (1., 2.) } else { (3., 4.) };
+   |                                ^^ help: consider adding suffix: `2.0_f64`
+
+error: default numeric fallback might occur
+  --> $DIR/default_numeric_fallback_f64.rs:20:46
+   |
+LL |         let x = if true { (1., 2.) } else { (3., 4.) };
+   |                                              ^^ help: consider adding suffix: `3.0_f64`
+
+error: default numeric fallback might occur
+  --> $DIR/default_numeric_fallback_f64.rs:20:50
+   |
+LL |         let x = if true { (1., 2.) } else { (3., 4.) };
+   |                                                  ^^ help: consider adding suffix: `4.0_f64`
+
+error: default numeric fallback might occur
+  --> $DIR/default_numeric_fallback_f64.rs:21:23
+   |
+LL |         let x = match 1. {
+   |                       ^^ help: consider adding suffix: `1.0_f64`
+
+error: default numeric fallback might occur
+  --> $DIR/default_numeric_fallback_f64.rs:22:18
+   |
+LL |             _ => 1.,
+   |                  ^^ help: consider adding suffix: `1.0_f64`
+
+error: default numeric fallback might occur
+  --> $DIR/default_numeric_fallback_f64.rs:40:21
+   |
+LL |             let y = 1.;
+   |                     ^^ help: consider adding suffix: `1.0_f64`
+
+error: default numeric fallback might occur
+  --> $DIR/default_numeric_fallback_f64.rs:48:21
+   |
+LL |             let y = 1.;
+   |                     ^^ help: consider adding suffix: `1.0_f64`
+
+error: default numeric fallback might occur
+  --> $DIR/default_numeric_fallback_f64.rs:54:21
+   |
+LL |             let y = 1.;
+   |                     ^^ help: consider adding suffix: `1.0_f64`
+
+error: default numeric fallback might occur
+  --> $DIR/default_numeric_fallback_f64.rs:66:9
+   |
+LL |         1.
+   |         ^^ help: consider adding suffix: `1.0_f64`
+
+error: default numeric fallback might occur
+  --> $DIR/default_numeric_fallback_f64.rs:72:27
+   |
+LL |         let f = || -> _ { 1. };
+   |                           ^^ help: consider adding suffix: `1.0_f64`
+
+error: default numeric fallback might occur
+  --> $DIR/default_numeric_fallback_f64.rs:76:29
+   |
+LL |         let f = || -> f64 { 1. };
+   |                             ^^ help: consider adding suffix: `1.0_f64`
+
+error: default numeric fallback might occur
+  --> $DIR/default_numeric_fallback_f64.rs:90:21
+   |
+LL |         generic_arg(1.);
+   |                     ^^ help: consider adding suffix: `1.0_f64`
+
+error: default numeric fallback might occur
+  --> $DIR/default_numeric_fallback_f64.rs:93:32
+   |
+LL |         let x: _ = generic_arg(1.);
+   |                                ^^ help: consider adding suffix: `1.0_f64`
+
+error: default numeric fallback might occur
+  --> $DIR/default_numeric_fallback_f64.rs:111:28
+   |
+LL |         GenericStruct { x: 1. };
+   |                            ^^ help: consider adding suffix: `1.0_f64`
+
+error: default numeric fallback might occur
+  --> $DIR/default_numeric_fallback_f64.rs:114:36
+   |
+LL |         let _ = GenericStruct { x: 1. };
+   |                                    ^^ help: consider adding suffix: `1.0_f64`
+
+error: default numeric fallback might occur
+  --> $DIR/default_numeric_fallback_f64.rs:132:24
+   |
+LL |         GenericEnum::X(1.);
+   |                        ^^ help: consider adding suffix: `1.0_f64`
+
+error: default numeric fallback might occur
+  --> $DIR/default_numeric_fallback_f64.rs:152:23
+   |
+LL |         s.generic_arg(1.);
+   |                       ^^ help: consider adding suffix: `1.0_f64`
+
+error: default numeric fallback might occur
+  --> $DIR/default_numeric_fallback_f64.rs:159:21
+   |
+LL |             let x = 22.;
+   |                     ^^^ help: consider adding suffix: `22.0_f64`
+...
+LL |         internal_macro!();
+   |         ------------------ in this macro invocation
+   |
+   = note: this error originates in the macro `internal_macro` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to 23 previous errors
+
diff --git a/tests/ui/default_numeric_fallback_i32.fixed b/tests/ui/default_numeric_fallback_i32.fixed
new file mode 100644
index 00000000000..55c082fcb19
--- /dev/null
+++ b/tests/ui/default_numeric_fallback_i32.fixed
@@ -0,0 +1,173 @@
+// run-rustfix
+// aux-build:macro_rules.rs
+
+#![warn(clippy::default_numeric_fallback)]
+#![allow(unused)]
+#![allow(clippy::never_loop)]
+#![allow(clippy::no_effect)]
+#![allow(clippy::unnecessary_operation)]
+#![allow(clippy::branches_sharing_code)]
+
+#[macro_use]
+extern crate macro_rules;
+
+mod basic_expr {
+    fn test() {
+        // Should lint unsuffixed literals typed `i32`.
+        let x = 22_i32;
+        let x = [1_i32, 2_i32, 3_i32];
+        let x = if true { (1_i32, 2_i32) } else { (3_i32, 4_i32) };
+        let x = match 1_i32 {
+            1_i32 => 1_i32,
+            _ => 2_i32,
+        };
+
+        // Should NOT lint suffixed literals.
+        let x = 22_i32;
+
+        // Should NOT lint literals in init expr if `Local` has a type annotation.
+        let x: [i32; 3] = [1, 2, 3];
+        let x: (i32, i32) = if true { (1, 2) } else { (3, 4) };
+        let x: _ = 1;
+    }
+}
+
+mod nested_local {
+    fn test() {
+        let x: _ = {
+            // Should lint this because this literal is not bound to any types.
+            let y = 1_i32;
+
+            // Should NOT lint this because this literal is bound to `_` of outer `Local`.
+            1
+        };
+
+        let x: _ = if true {
+            // Should lint this because this literal is not bound to any types.
+            let y = 1_i32;
+
+            // Should NOT lint this because this literal is bound to `_` of outer `Local`.
+            1
+        } else {
+            // Should lint this because this literal is not bound to any types.
+            let y = 1_i32;
+
+            // Should NOT lint this because this literal is bound to `_` of outer `Local`.
+            2
+        };
+    }
+}
+
+mod function_def {
+    fn ret_i32() -> i32 {
+        // Even though the output type is specified,
+        // this unsuffixed literal is linted to reduce heuristics and keep codebase simple.
+        1_i32
+    }
+
+    fn test() {
+        // Should lint this because return type is inferred to `i32` and NOT bound to a concrete
+        // type.
+        let f = || -> _ { 1_i32 };
+
+        // Even though the output type is specified,
+        // this unsuffixed literal is linted to reduce heuristics and keep codebase simple.
+        let f = || -> i32 { 1_i32 };
+    }
+}
+
+mod function_calls {
+    fn concrete_arg(x: i32) {}
+
+    fn generic_arg<T>(t: T) {}
+
+    fn test() {
+        // Should NOT lint this because the argument type is bound to a concrete type.
+        concrete_arg(1);
+
+        // Should lint this because the argument type is inferred to `i32` and NOT bound to a concrete type.
+        generic_arg(1_i32);
+
+        // Should lint this because the argument type is inferred to `i32` and NOT bound to a concrete type.
+        let x: _ = generic_arg(1_i32);
+    }
+}
+
+mod struct_ctor {
+    struct ConcreteStruct {
+        x: i32,
+    }
+
+    struct GenericStruct<T> {
+        x: T,
+    }
+
+    fn test() {
+        // Should NOT lint this because the field type is bound to a concrete type.
+        ConcreteStruct { x: 1 };
+
+        // Should lint this because the field type is inferred to `i32` and NOT bound to a concrete type.
+        GenericStruct { x: 1_i32 };
+
+        // Should lint this because the field type is inferred to `i32` and NOT bound to a concrete type.
+        let _ = GenericStruct { x: 1_i32 };
+    }
+}
+
+mod enum_ctor {
+    enum ConcreteEnum {
+        X(i32),
+    }
+
+    enum GenericEnum<T> {
+        X(T),
+    }
+
+    fn test() {
+        // Should NOT lint this because the field type is bound to a concrete type.
+        ConcreteEnum::X(1);
+
+        // Should lint this because the field type is inferred to `i32` and NOT bound to a concrete type.
+        GenericEnum::X(1_i32);
+    }
+}
+
+mod method_calls {
+    struct StructForMethodCallTest {}
+
+    impl StructForMethodCallTest {
+        fn concrete_arg(&self, x: i32) {}
+
+        fn generic_arg<T>(&self, t: T) {}
+    }
+
+    fn test() {
+        let s = StructForMethodCallTest {};
+
+        // Should NOT lint this because the argument type is bound to a concrete type.
+        s.concrete_arg(1);
+
+        // Should lint this because the argument type is bound to a concrete type.
+        s.generic_arg(1_i32);
+    }
+}
+
+mod in_macro {
+    macro_rules! internal_macro {
+        () => {
+            let x = 22_i32;
+        };
+    }
+
+    // Should lint in internal macro.
+    fn internal() {
+        internal_macro!();
+    }
+
+    // Should NOT lint in external macro.
+    fn external() {
+        default_numeric_fallback!();
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/default_numeric_fallback.rs b/tests/ui/default_numeric_fallback_i32.rs
index c0625fd1b75..e0a4828ce9f 100644
--- a/tests/ui/default_numeric_fallback.rs
+++ b/tests/ui/default_numeric_fallback_i32.rs
@@ -1,3 +1,4 @@
+// run-rustfix
 // aux-build:macro_rules.rs
 
 #![warn(clippy::default_numeric_fallback)]
@@ -21,15 +22,10 @@ mod basic_expr {
             _ => 2,
         };
 
-        // Should lint unsuffixed literals typed `f64`.
-        let x = 0.12;
-
         // Should NOT lint suffixed literals.
         let x = 22_i32;
-        let x = 0.12_f64;
 
         // Should NOT lint literals in init expr if `Local` has a type annotation.
-        let x: f64 = 0.1;
         let x: [i32; 3] = [1, 2, 3];
         let x: (i32, i32) = if true { (1, 2) } else { (3, 4) };
         let x: _ = 1;
@@ -118,6 +114,24 @@ mod struct_ctor {
     }
 }
 
+mod enum_ctor {
+    enum ConcreteEnum {
+        X(i32),
+    }
+
+    enum GenericEnum<T> {
+        X(T),
+    }
+
+    fn test() {
+        // Should NOT lint this because the field type is bound to a concrete type.
+        ConcreteEnum::X(1);
+
+        // Should lint this because the field type is inferred to `i32` and NOT bound to a concrete type.
+        GenericEnum::X(1);
+    }
+}
+
 mod method_calls {
     struct StructForMethodCallTest {}
 
diff --git a/tests/ui/default_numeric_fallback.stderr b/tests/ui/default_numeric_fallback_i32.stderr
index 5862cd936ac..5edf48b2020 100644
--- a/tests/ui/default_numeric_fallback.stderr
+++ b/tests/ui/default_numeric_fallback_i32.stderr
@@ -1,5 +1,5 @@
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback.rs:16:17
+  --> $DIR/default_numeric_fallback_i32.rs:17:17
    |
 LL |         let x = 22;
    |                 ^^ help: consider adding suffix: `22_i32`
@@ -7,145 +7,145 @@ LL |         let x = 22;
    = note: `-D clippy::default-numeric-fallback` implied by `-D warnings`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback.rs:17:18
+  --> $DIR/default_numeric_fallback_i32.rs:18:18
    |
 LL |         let x = [1, 2, 3];
    |                  ^ help: consider adding suffix: `1_i32`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback.rs:17:21
+  --> $DIR/default_numeric_fallback_i32.rs:18:21
    |
 LL |         let x = [1, 2, 3];
    |                     ^ help: consider adding suffix: `2_i32`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback.rs:17:24
+  --> $DIR/default_numeric_fallback_i32.rs:18:24
    |
 LL |         let x = [1, 2, 3];
    |                        ^ help: consider adding suffix: `3_i32`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback.rs:18:28
+  --> $DIR/default_numeric_fallback_i32.rs:19:28
    |
 LL |         let x = if true { (1, 2) } else { (3, 4) };
    |                            ^ help: consider adding suffix: `1_i32`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback.rs:18:31
+  --> $DIR/default_numeric_fallback_i32.rs:19:31
    |
 LL |         let x = if true { (1, 2) } else { (3, 4) };
    |                               ^ help: consider adding suffix: `2_i32`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback.rs:18:44
+  --> $DIR/default_numeric_fallback_i32.rs:19:44
    |
 LL |         let x = if true { (1, 2) } else { (3, 4) };
    |                                            ^ help: consider adding suffix: `3_i32`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback.rs:18:47
+  --> $DIR/default_numeric_fallback_i32.rs:19:47
    |
 LL |         let x = if true { (1, 2) } else { (3, 4) };
    |                                               ^ help: consider adding suffix: `4_i32`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback.rs:19:23
+  --> $DIR/default_numeric_fallback_i32.rs:20:23
    |
 LL |         let x = match 1 {
    |                       ^ help: consider adding suffix: `1_i32`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback.rs:20:13
+  --> $DIR/default_numeric_fallback_i32.rs:21:13
    |
 LL |             1 => 1,
    |             ^ help: consider adding suffix: `1_i32`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback.rs:20:18
+  --> $DIR/default_numeric_fallback_i32.rs:21:18
    |
 LL |             1 => 1,
    |                  ^ help: consider adding suffix: `1_i32`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback.rs:21:18
+  --> $DIR/default_numeric_fallback_i32.rs:22:18
    |
 LL |             _ => 2,
    |                  ^ help: consider adding suffix: `2_i32`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback.rs:25:17
-   |
-LL |         let x = 0.12;
-   |                 ^^^^ help: consider adding suffix: `0.12_f64`
-
-error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback.rs:43:21
+  --> $DIR/default_numeric_fallback_i32.rs:39:21
    |
 LL |             let y = 1;
    |                     ^ help: consider adding suffix: `1_i32`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback.rs:51:21
+  --> $DIR/default_numeric_fallback_i32.rs:47:21
    |
 LL |             let y = 1;
    |                     ^ help: consider adding suffix: `1_i32`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback.rs:57:21
+  --> $DIR/default_numeric_fallback_i32.rs:53:21
    |
 LL |             let y = 1;
    |                     ^ help: consider adding suffix: `1_i32`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback.rs:69:9
+  --> $DIR/default_numeric_fallback_i32.rs:65:9
    |
 LL |         1
    |         ^ help: consider adding suffix: `1_i32`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback.rs:75:27
+  --> $DIR/default_numeric_fallback_i32.rs:71:27
    |
 LL |         let f = || -> _ { 1 };
    |                           ^ help: consider adding suffix: `1_i32`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback.rs:79:29
+  --> $DIR/default_numeric_fallback_i32.rs:75:29
    |
 LL |         let f = || -> i32 { 1 };
    |                             ^ help: consider adding suffix: `1_i32`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback.rs:93:21
+  --> $DIR/default_numeric_fallback_i32.rs:89:21
    |
 LL |         generic_arg(1);
    |                     ^ help: consider adding suffix: `1_i32`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback.rs:96:32
+  --> $DIR/default_numeric_fallback_i32.rs:92:32
    |
 LL |         let x: _ = generic_arg(1);
    |                                ^ help: consider adding suffix: `1_i32`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback.rs:114:28
+  --> $DIR/default_numeric_fallback_i32.rs:110:28
    |
 LL |         GenericStruct { x: 1 };
    |                            ^ help: consider adding suffix: `1_i32`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback.rs:117:36
+  --> $DIR/default_numeric_fallback_i32.rs:113:36
    |
 LL |         let _ = GenericStruct { x: 1 };
    |                                    ^ help: consider adding suffix: `1_i32`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback.rs:137:23
+  --> $DIR/default_numeric_fallback_i32.rs:131:24
+   |
+LL |         GenericEnum::X(1);
+   |                        ^ help: consider adding suffix: `1_i32`
+
+error: default numeric fallback might occur
+  --> $DIR/default_numeric_fallback_i32.rs:151:23
    |
 LL |         s.generic_arg(1);
    |                       ^ help: consider adding suffix: `1_i32`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback.rs:144:21
+  --> $DIR/default_numeric_fallback_i32.rs:158:21
    |
 LL |             let x = 22;
    |                     ^^ help: consider adding suffix: `22_i32`