1 // aux-build:proc_macro_derive.rs
2 // aux-build:macro_rules.rs
4 #![warn(clippy::field_reassign_with_default)]
7 extern crate proc_macro_derive;
9 extern crate macro_rules;
11 // Don't lint on derives that derive `Default`
12 // See https://github.com/rust-lang/rust-clippy/issues/6545
13 #[derive(FieldReassignWithDefault)]
40 ($key:ident: $value:tt) => {{
41 let mut data = $crate::D::default();
42 data.$key = Some($value);
47 /// Implements .next() that returns a different number each time.
48 struct SideEffect(i32);
51 fn new() -> SideEffect {
54 fn next(&mut self) -> i32 {
61 // wrong, produces first error in stderr
62 let mut a: A = Default::default();
66 let mut a: A = Default::default();
75 let mut a: A = Default::default();
81 let mut a: A = Default::default();
86 let mut a: A = Default::default();
90 let b: B = B { i: 42, j: 24 };
93 let mut b: B = B { i: 42, j: 24 };
97 let mut b = B { i: 15, j: 16 };
98 let mut a: A = Default::default();
101 // wrong, produces second error in stderr
102 let mut a: A = Default::default();
106 // wrong, produces third error in stderr
107 let mut a: A = Default::default();
112 // wrong, produces fourth error in stderr
113 let mut a = A::default();
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();
122 // wrong, produces the fifth error in stderr
123 let mut a: A = Default::default();
124 a.i = Default::default();
126 // wrong, produces the sixth error in stderr
127 let mut a: A = Default::default();
128 a.i = Default::default();
131 // right, because an assignment refers to another field
132 let mut x = A::default();
134 x.j = 21 + x.i as i64;
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();
142 x.i = side_effect.next();
144 // don't lint - some private fields
145 let mut x = m::F::default();
148 // don't expand macros in the suggestion (#6522)
149 let mut a: C = C::default();
152 // Don't lint in external macros
153 field_reassign_with_default!();
155 // be sure suggestion is correct with generics
156 let mut a: Wrapper<bool> = Default::default();
159 let mut a: WrapperMulti<i32, i64> = Default::default();
162 // Don't lint in macros
182 struct WrapperMulti<T, U> {
188 use std::sync::atomic::AtomicBool;
191 // do not lint: type implements `Drop` but not all fields are `Copy`
192 #[derive(Clone, Default)]
193 pub struct ImplDropNotAllCopy {
195 delay_data_sync: Arc<AtomicBool>,
198 impl Drop for ImplDropNotAllCopy {
204 impl ImplDropNotAllCopy {
205 fn new(name: &str) -> Self {
206 let mut f = ImplDropNotAllCopy::default();
207 f.name = name.to_owned();
213 // lint: type implements `Drop` and all fields are `Copy`
214 #[derive(Clone, Default)]
215 pub struct ImplDropAllCopy {
217 delay_data_sync: bool,
220 impl Drop for ImplDropAllCopy {
226 impl ImplDropAllCopy {
227 fn new(name: &str) -> Self {
228 let mut f = ImplDropAllCopy::default();
235 // lint: type does not implement `Drop` though all fields are `Copy`
236 #[derive(Clone, Default)]
237 pub struct NoDropAllCopy {
239 delay_data_sync: bool,
243 fn new(name: &str) -> Self {
244 let mut f = NoDropAllCopy::default();