]> git.proxmox.com Git - rustc.git/blob - src/tools/clippy/tests/ui/field_reassign_with_default.rs
New upstream version 1.55.0+dfsg1
[rustc.git] / src / tools / clippy / tests / ui / field_reassign_with_default.rs
1 // aux-build:proc_macro_derive.rs
2 // aux-build:macro_rules.rs
3
4 #![warn(clippy::field_reassign_with_default)]
5
6 #[macro_use]
7 extern crate proc_macro_derive;
8 #[macro_use]
9 extern crate macro_rules;
10
11 // Don't lint on derives that derive `Default`
12 // See https://github.com/rust-lang/rust-clippy/issues/6545
13 #[derive(FieldReassignWithDefault)]
14 struct DerivedStruct;
15
16 #[derive(Default)]
17 struct A {
18 i: i32,
19 j: i64,
20 }
21
22 struct B {
23 i: i32,
24 j: i64,
25 }
26
27 #[derive(Default)]
28 struct C {
29 i: Vec<i32>,
30 j: i64,
31 }
32
33 #[derive(Default)]
34 struct D {
35 a: Option<i32>,
36 b: Option<i32>,
37 }
38
39 macro_rules! m {
40 ($key:ident: $value:tt) => {{
41 let mut data = $crate::D::default();
42 data.$key = Some($value);
43 data
44 }};
45 }
46
47 /// Implements .next() that returns a different number each time.
48 struct SideEffect(i32);
49
50 impl SideEffect {
51 fn new() -> SideEffect {
52 SideEffect(0)
53 }
54 fn next(&mut self) -> i32 {
55 self.0 += 1;
56 self.0
57 }
58 }
59
60 fn main() {
61 // wrong, produces first error in stderr
62 let mut a: A = Default::default();
63 a.i = 42;
64
65 // right
66 let mut a: A = Default::default();
67
68 // right
69 let a = A {
70 i: 42,
71 ..Default::default()
72 };
73
74 // right
75 let mut a: A = Default::default();
76 if a.i == 0 {
77 a.j = 12;
78 }
79
80 // right
81 let mut a: A = Default::default();
82 let b = 5;
83
84 // right
85 let mut b = 32;
86 let mut a: A = Default::default();
87 b = 2;
88
89 // right
90 let b: B = B { i: 42, j: 24 };
91
92 // right
93 let mut b: B = B { i: 42, j: 24 };
94 b.i = 52;
95
96 // right
97 let mut b = B { i: 15, j: 16 };
98 let mut a: A = Default::default();
99 b.i = 2;
100
101 // wrong, produces second error in stderr
102 let mut a: A = Default::default();
103 a.j = 43;
104 a.i = 42;
105
106 // wrong, produces third error in stderr
107 let mut a: A = Default::default();
108 a.i = 42;
109 a.j = 43;
110 a.j = 44;
111
112 // wrong, produces fourth error in stderr
113 let mut a = A::default();
114 a.i = 42;
115
116 // wrong, but does not produce an error in stderr, because we can't produce a correct kind of
117 // suggestion with current implementation
118 let mut c: (i32, i32) = Default::default();
119 c.0 = 42;
120 c.1 = 21;
121
122 // wrong, produces the fifth error in stderr
123 let mut a: A = Default::default();
124 a.i = Default::default();
125
126 // wrong, produces the sixth error in stderr
127 let mut a: A = Default::default();
128 a.i = Default::default();
129 a.j = 45;
130
131 // right, because an assignment refers to another field
132 let mut x = A::default();
133 x.i = 42;
134 x.j = 21 + x.i as i64;
135
136 // right, we bail out if there's a reassignment to the same variable, since there is a risk of
137 // side-effects affecting the outcome
138 let mut x = A::default();
139 let mut side_effect = SideEffect::new();
140 x.i = side_effect.next();
141 x.j = 2;
142 x.i = side_effect.next();
143
144 // don't lint - some private fields
145 let mut x = m::F::default();
146 x.a = 1;
147
148 // don't expand macros in the suggestion (#6522)
149 let mut a: C = C::default();
150 a.i = vec![1];
151
152 // Don't lint in external macros
153 field_reassign_with_default!();
154
155 // be sure suggestion is correct with generics
156 let mut a: Wrapper<bool> = Default::default();
157 a.i = true;
158
159 let mut a: WrapperMulti<i32, i64> = Default::default();
160 a.i = 42;
161
162 // Don't lint in macros
163 m! {
164 a: 42
165 };
166 }
167
168 mod m {
169 #[derive(Default)]
170 pub struct F {
171 pub a: u64,
172 b: u64,
173 }
174 }
175
176 #[derive(Default)]
177 struct Wrapper<T> {
178 i: T,
179 }
180
181 #[derive(Default)]
182 struct WrapperMulti<T, U> {
183 i: T,
184 j: U,
185 }