1 // run-rustfix
2 // aux-build:macro_rules.rs
3 
4 #![warn(clippy::default_numeric_fallback)]
5 #![allow(unused)]
6 #![allow(clippy::never_loop)]
7 #![allow(clippy::no_effect)]
8 #![allow(clippy::unnecessary_operation)]
9 #![allow(clippy::branches_sharing_code)]
10 #![allow(clippy::match_single_binding)]
11 
12 #[macro_use]
13 extern crate macro_rules;
14 
15 mod basic_expr {
test()16     fn test() {
17         // Should lint unsuffixed literals typed `f64`.
18         let x = 0.12;
19         let x = [1., 2., 3.];
20         let x = if true { (1., 2.) } else { (3., 4.) };
21         let x = match 1. {
22             _ => 1.,
23         };
24 
25         // Should NOT lint suffixed literals.
26         let x = 0.12_f64;
27 
28         // Should NOT lint literals in init expr if `Local` has a type annotation.
29         let x: f64 = 0.1;
30         let x: [f64; 3] = [1., 2., 3.];
31         let x: (f64, f64) = if true { (1., 2.) } else { (3., 4.) };
32         let x: _ = 1.;
33     }
34 }
35 
36 mod nested_local {
test()37     fn test() {
38         let x: _ = {
39             // Should lint this because this literal is not bound to any types.
40             let y = 1.;
41 
42             // Should NOT lint this because this literal is bound to `_` of outer `Local`.
43             1.
44         };
45 
46         let x: _ = if true {
47             // Should lint this because this literal is not bound to any types.
48             let y = 1.;
49 
50             // Should NOT lint this because this literal is bound to `_` of outer `Local`.
51             1.
52         } else {
53             // Should lint this because this literal is not bound to any types.
54             let y = 1.;
55 
56             // Should NOT lint this because this literal is bound to `_` of outer `Local`.
57             2.
58         };
59     }
60 }
61 
62 mod function_def {
ret_f64() -> f6463     fn ret_f64() -> f64 {
64         // Even though the output type is specified,
65         // this unsuffixed literal is linted to reduce heuristics and keep codebase simple.
66         1.
67     }
68 
test()69     fn test() {
70         // Should lint this because return type is inferred to `f64` and NOT bound to a concrete
71         // type.
72         let f = || -> _ { 1. };
73 
74         // Even though the output type is specified,
75         // this unsuffixed literal is linted to reduce heuristics and keep codebase simple.
76         let f = || -> f64 { 1. };
77     }
78 }
79 
80 mod function_calls {
concrete_arg(f: f64)81     fn concrete_arg(f: f64) {}
82 
generic_arg<T>(t: T)83     fn generic_arg<T>(t: T) {}
84 
test()85     fn test() {
86         // Should NOT lint this because the argument type is bound to a concrete type.
87         concrete_arg(1.);
88 
89         // Should lint this because the argument type is inferred to `f64` and NOT bound to a concrete type.
90         generic_arg(1.);
91 
92         // Should lint this because the argument type is inferred to `f64` and NOT bound to a concrete type.
93         let x: _ = generic_arg(1.);
94     }
95 }
96 
97 mod struct_ctor {
98     struct ConcreteStruct {
99         x: f64,
100     }
101 
102     struct GenericStruct<T> {
103         x: T,
104     }
105 
test()106     fn test() {
107         // Should NOT lint this because the field type is bound to a concrete type.
108         ConcreteStruct { x: 1. };
109 
110         // Should lint this because the field type is inferred to `f64` and NOT bound to a concrete type.
111         GenericStruct { x: 1. };
112 
113         // Should lint this because the field type is inferred to `f64` and NOT bound to a concrete type.
114         let _ = GenericStruct { x: 1. };
115     }
116 }
117 
118 mod enum_ctor {
119     enum ConcreteEnum {
120         X(f64),
121     }
122 
123     enum GenericEnum<T> {
124         X(T),
125     }
126 
test()127     fn test() {
128         // Should NOT lint this because the field type is bound to a concrete type.
129         ConcreteEnum::X(1.);
130 
131         // Should lint this because the field type is inferred to `f64` and NOT bound to a concrete type.
132         GenericEnum::X(1.);
133     }
134 }
135 
136 mod method_calls {
137     struct StructForMethodCallTest {}
138 
139     impl StructForMethodCallTest {
concrete_arg(&self, f: f64)140         fn concrete_arg(&self, f: f64) {}
141 
generic_arg<T>(&self, t: T)142         fn generic_arg<T>(&self, t: T) {}
143     }
144 
test()145     fn test() {
146         let s = StructForMethodCallTest {};
147 
148         // Should NOT lint this because the argument type is bound to a concrete type.
149         s.concrete_arg(1.);
150 
151         // Should lint this because the argument type is bound to a concrete type.
152         s.generic_arg(1.);
153     }
154 }
155 
156 mod in_macro {
157     macro_rules! internal_macro {
158         () => {
159             let x = 22.;
160         };
161     }
162 
163     // Should lint in internal macro.
internal()164     fn internal() {
165         internal_macro!();
166     }
167 
168     // Should NOT lint in external macro.
external()169     fn external() {
170         default_numeric_fallback!();
171     }
172 }
173 
main()174 fn main() {}
175