Skip to content

Commit 5be4dc9

Browse files
committed
[new_without_default]: make the suggestion machine-applicable
Now that generics and lifetimes are output as expected, the lint should be applicable.
1 parent 7c4d276 commit 5be4dc9

File tree

4 files changed

+312
-9
lines changed

4 files changed

+312
-9
lines changed

clippy_lints/src/new_without_default.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ impl<'tcx> LateLintPass<'tcx> for NewWithoutDefault {
155155
&generics_sugg,
156156
&where_clause_sugg
157157
),
158-
Applicability::MaybeIncorrect,
158+
Applicability::MachineApplicable,
159159
);
160160
},
161161
);

tests/ui/new_without_default.fixed

+302
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,302 @@
1+
//@run-rustfix
2+
#![allow(
3+
dead_code,
4+
clippy::missing_safety_doc,
5+
clippy::extra_unused_lifetimes,
6+
clippy::extra_unused_type_parameters
7+
)]
8+
#![warn(clippy::new_without_default)]
9+
10+
pub struct Foo;
11+
12+
impl Default for Foo {
13+
fn default() -> Self {
14+
Self::new()
15+
}
16+
}
17+
18+
impl Foo {
19+
pub fn new() -> Foo {
20+
Foo
21+
}
22+
}
23+
24+
pub struct Bar;
25+
26+
impl Default for Bar {
27+
fn default() -> Self {
28+
Self::new()
29+
}
30+
}
31+
32+
impl Bar {
33+
pub fn new() -> Self {
34+
Bar
35+
}
36+
}
37+
38+
pub struct Ok;
39+
40+
impl Ok {
41+
pub fn new() -> Self {
42+
Ok
43+
}
44+
}
45+
46+
impl Default for Ok {
47+
fn default() -> Self {
48+
Ok
49+
}
50+
}
51+
52+
pub struct Params;
53+
54+
impl Params {
55+
pub fn new(_: u32) -> Self {
56+
Params
57+
}
58+
}
59+
60+
pub struct GenericsOk<T> {
61+
bar: T,
62+
}
63+
64+
impl<U> Default for GenericsOk<U> {
65+
fn default() -> Self {
66+
unimplemented!();
67+
}
68+
}
69+
70+
impl<'c, V> GenericsOk<V> {
71+
pub fn new() -> GenericsOk<V> {
72+
unimplemented!()
73+
}
74+
}
75+
76+
pub struct LtOk<'a> {
77+
foo: &'a bool,
78+
}
79+
80+
impl<'b> Default for LtOk<'b> {
81+
fn default() -> Self {
82+
unimplemented!();
83+
}
84+
}
85+
86+
impl<'c> LtOk<'c> {
87+
pub fn new() -> LtOk<'c> {
88+
unimplemented!()
89+
}
90+
}
91+
92+
pub struct LtKo<'a> {
93+
foo: &'a bool,
94+
}
95+
96+
impl<'c> Default for LtKo<'c> {
97+
fn default() -> Self {
98+
Self::new()
99+
}
100+
}
101+
102+
impl<'c> LtKo<'c> {
103+
pub fn new() -> LtKo<'c> {
104+
unimplemented!()
105+
}
106+
}
107+
108+
struct Private;
109+
110+
impl Private {
111+
fn new() -> Private {
112+
unimplemented!()
113+
} // We don't lint private items
114+
}
115+
116+
struct PrivateStruct;
117+
118+
impl PrivateStruct {
119+
pub fn new() -> PrivateStruct {
120+
unimplemented!()
121+
} // We don't lint public items on private structs
122+
}
123+
124+
pub struct PrivateItem;
125+
126+
impl PrivateItem {
127+
fn new() -> PrivateItem {
128+
unimplemented!()
129+
} // We don't lint private items on public structs
130+
}
131+
132+
struct Const;
133+
134+
impl Const {
135+
pub const fn new() -> Const {
136+
Const
137+
} // const fns can't be implemented via Default
138+
}
139+
140+
pub struct IgnoreGenericNew;
141+
142+
impl IgnoreGenericNew {
143+
pub fn new<T>() -> Self {
144+
IgnoreGenericNew
145+
} // the derived Default does not make sense here as the result depends on T
146+
}
147+
148+
pub trait TraitWithNew: Sized {
149+
fn new() -> Self {
150+
panic!()
151+
}
152+
}
153+
154+
pub struct IgnoreUnsafeNew;
155+
156+
impl IgnoreUnsafeNew {
157+
pub unsafe fn new() -> Self {
158+
IgnoreUnsafeNew
159+
}
160+
}
161+
162+
#[derive(Default)]
163+
pub struct OptionRefWrapper<'a, T>(Option<&'a T>);
164+
165+
impl<'a, T> OptionRefWrapper<'a, T> {
166+
pub fn new() -> Self {
167+
OptionRefWrapper(None)
168+
}
169+
}
170+
171+
pub struct Allow(Foo);
172+
173+
impl Allow {
174+
#[allow(clippy::new_without_default)]
175+
pub fn new() -> Self {
176+
unimplemented!()
177+
}
178+
}
179+
180+
pub struct AllowDerive;
181+
182+
impl AllowDerive {
183+
#[allow(clippy::new_without_default)]
184+
pub fn new() -> Self {
185+
unimplemented!()
186+
}
187+
}
188+
189+
pub struct NewNotEqualToDerive {
190+
foo: i32,
191+
}
192+
193+
impl Default for NewNotEqualToDerive {
194+
fn default() -> Self {
195+
Self::new()
196+
}
197+
}
198+
199+
impl NewNotEqualToDerive {
200+
// This `new` implementation is not equal to a derived `Default`, so do not suggest deriving.
201+
pub fn new() -> Self {
202+
NewNotEqualToDerive { foo: 1 }
203+
}
204+
}
205+
206+
// see #6933
207+
pub struct FooGenerics<T>(std::marker::PhantomData<T>);
208+
impl<T> Default for FooGenerics<T> {
209+
fn default() -> Self {
210+
Self::new()
211+
}
212+
}
213+
214+
impl<T> FooGenerics<T> {
215+
pub fn new() -> Self {
216+
Self(Default::default())
217+
}
218+
}
219+
220+
pub struct BarGenerics<T>(std::marker::PhantomData<T>);
221+
impl<T: Copy> Default for BarGenerics<T> {
222+
fn default() -> Self {
223+
Self::new()
224+
}
225+
}
226+
227+
impl<T: Copy> BarGenerics<T> {
228+
pub fn new() -> Self {
229+
Self(Default::default())
230+
}
231+
}
232+
233+
pub mod issue7220 {
234+
pub struct Foo<T> {
235+
_bar: *mut T,
236+
}
237+
238+
impl<T> Default for Foo<T> {
239+
fn default() -> Self {
240+
Self::new()
241+
}
242+
}
243+
244+
impl<T> Foo<T> {
245+
pub fn new() -> Self {
246+
todo!()
247+
}
248+
}
249+
}
250+
251+
// see issue #8152
252+
// This should not create any lints
253+
pub struct DocHidden;
254+
impl DocHidden {
255+
#[doc(hidden)]
256+
pub fn new() -> Self {
257+
DocHidden
258+
}
259+
}
260+
261+
fn main() {}
262+
263+
pub struct IgnoreConstGenericNew(usize);
264+
impl IgnoreConstGenericNew {
265+
pub fn new<const N: usize>() -> Self {
266+
Self(N)
267+
}
268+
}
269+
270+
pub struct IgnoreLifetimeNew;
271+
impl IgnoreLifetimeNew {
272+
pub fn new<'a>() -> Self {
273+
Self
274+
}
275+
}
276+
277+
// From issue #11267
278+
279+
pub struct MyStruct<K, V>
280+
where
281+
K: std::hash::Hash + Eq + PartialEq,
282+
{
283+
_kv: Option<(K, V)>,
284+
}
285+
286+
impl<K, V> Default for MyStruct<K, V>
287+
where
288+
K: std::hash::Hash + Eq + PartialEq,
289+
{
290+
fn default() -> Self {
291+
Self::new()
292+
}
293+
}
294+
295+
impl<K, V> MyStruct<K, V>
296+
where
297+
K: std::hash::Hash + Eq + PartialEq,
298+
{
299+
pub fn new() -> Self {
300+
Self { _kv: None }
301+
}
302+
}

tests/ui/new_without_default.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
//@run-rustfix
12
#![allow(
23
dead_code,
34
clippy::missing_safety_doc,

tests/ui/new_without_default.stderr

+8-8
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error: you should consider adding a `Default` implementation for `Foo`
2-
--> $DIR/new_without_default.rs:12:5
2+
--> $DIR/new_without_default.rs:13:5
33
|
44
LL | / pub fn new() -> Foo {
55
LL | | Foo
@@ -17,7 +17,7 @@ LL + }
1717
|
1818

1919
error: you should consider adding a `Default` implementation for `Bar`
20-
--> $DIR/new_without_default.rs:20:5
20+
--> $DIR/new_without_default.rs:21:5
2121
|
2222
LL | / pub fn new() -> Self {
2323
LL | | Bar
@@ -34,7 +34,7 @@ LL + }
3434
|
3535

3636
error: you should consider adding a `Default` implementation for `LtKo<'c>`
37-
--> $DIR/new_without_default.rs:84:5
37+
--> $DIR/new_without_default.rs:85:5
3838
|
3939
LL | / pub fn new() -> LtKo<'c> {
4040
LL | | unimplemented!()
@@ -51,7 +51,7 @@ LL + }
5151
|
5252

5353
error: you should consider adding a `Default` implementation for `NewNotEqualToDerive`
54-
--> $DIR/new_without_default.rs:176:5
54+
--> $DIR/new_without_default.rs:177:5
5555
|
5656
LL | / pub fn new() -> Self {
5757
LL | | NewNotEqualToDerive { foo: 1 }
@@ -68,7 +68,7 @@ LL + }
6868
|
6969

7070
error: you should consider adding a `Default` implementation for `FooGenerics<T>`
71-
--> $DIR/new_without_default.rs:184:5
71+
--> $DIR/new_without_default.rs:185:5
7272
|
7373
LL | / pub fn new() -> Self {
7474
LL | | Self(Default::default())
@@ -85,7 +85,7 @@ LL + }
8585
|
8686

8787
error: you should consider adding a `Default` implementation for `BarGenerics<T>`
88-
--> $DIR/new_without_default.rs:191:5
88+
--> $DIR/new_without_default.rs:192:5
8989
|
9090
LL | / pub fn new() -> Self {
9191
LL | | Self(Default::default())
@@ -102,7 +102,7 @@ LL + }
102102
|
103103

104104
error: you should consider adding a `Default` implementation for `Foo<T>`
105-
--> $DIR/new_without_default.rs:202:9
105+
--> $DIR/new_without_default.rs:203:9
106106
|
107107
LL | / pub fn new() -> Self {
108108
LL | | todo!()
@@ -121,7 +121,7 @@ LL ~ impl<T> Foo<T> {
121121
|
122122

123123
error: you should consider adding a `Default` implementation for `MyStruct<K, V>`
124-
--> $DIR/new_without_default.rs:247:5
124+
--> $DIR/new_without_default.rs:248:5
125125
|
126126
LL | / pub fn new() -> Self {
127127
LL | | Self { _kv: None }

0 commit comments

Comments
 (0)