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