]>
Commit | Line | Data |
---|---|---|
f20569fa XL |
1 | // run-rustfix |
2 | // edition:2018 | |
3 | // aux-build:proc_macro_derive.rs | |
4 | ||
5 | #![warn(clippy::use_self)] | |
6 | #![allow(dead_code)] | |
136023e0 XL |
7 | #![allow( |
8 | clippy::should_implement_trait, | |
9 | clippy::upper_case_acronyms, | |
10 | clippy::from_over_into, | |
11 | clippy::self_named_constructors | |
12 | )] | |
f20569fa XL |
13 | |
14 | #[macro_use] | |
15 | extern crate proc_macro_derive; | |
16 | ||
17 | fn main() {} | |
18 | ||
19 | mod use_self { | |
20 | struct Foo {} | |
21 | ||
22 | impl Foo { | |
23 | fn new() -> Self { | |
24 | Self {} | |
25 | } | |
26 | fn test() -> Self { | |
27 | Self::new() | |
28 | } | |
29 | } | |
30 | ||
31 | impl Default for Foo { | |
32 | fn default() -> Self { | |
33 | Self::new() | |
34 | } | |
35 | } | |
36 | } | |
37 | ||
38 | mod better { | |
39 | struct Foo {} | |
40 | ||
41 | impl Foo { | |
42 | fn new() -> Self { | |
43 | Self {} | |
44 | } | |
45 | fn test() -> Self { | |
46 | Self::new() | |
47 | } | |
48 | } | |
49 | ||
50 | impl Default for Foo { | |
51 | fn default() -> Self { | |
52 | Self::new() | |
53 | } | |
54 | } | |
55 | } | |
56 | ||
57 | mod lifetimes { | |
58 | struct Foo<'a> { | |
59 | foo_str: &'a str, | |
60 | } | |
61 | ||
62 | impl<'a> Foo<'a> { | |
63 | // Cannot use `Self` as return type, because the function is actually `fn foo<'b>(s: &'b str) -> | |
64 | // Foo<'b>` | |
65 | fn foo(s: &str) -> Foo { | |
66 | Foo { foo_str: s } | |
67 | } | |
68 | // cannot replace with `Self`, because that's `Foo<'a>` | |
69 | fn bar() -> Foo<'static> { | |
70 | Foo { foo_str: "foo" } | |
71 | } | |
72 | ||
73 | // FIXME: the lint does not handle lifetimed struct | |
74 | // `Self` should be applicable here | |
75 | fn clone(&self) -> Foo<'a> { | |
76 | Foo { foo_str: self.foo_str } | |
77 | } | |
78 | } | |
79 | } | |
80 | ||
81 | mod issue2894 { | |
82 | trait IntoBytes { | |
cdc7bbd5 | 83 | fn to_bytes(self) -> Vec<u8>; |
f20569fa XL |
84 | } |
85 | ||
86 | // This should not be linted | |
87 | impl IntoBytes for u8 { | |
cdc7bbd5 XL |
88 | fn to_bytes(self) -> Vec<u8> { |
89 | vec![self] | |
f20569fa XL |
90 | } |
91 | } | |
92 | } | |
93 | ||
94 | mod existential { | |
95 | struct Foo; | |
96 | ||
97 | impl Foo { | |
98 | fn bad(foos: &[Self]) -> impl Iterator<Item = &Self> { | |
99 | foos.iter() | |
100 | } | |
101 | ||
102 | fn good(foos: &[Self]) -> impl Iterator<Item = &Self> { | |
103 | foos.iter() | |
104 | } | |
105 | } | |
106 | } | |
107 | ||
108 | mod tuple_structs { | |
109 | pub struct TS(i32); | |
110 | ||
111 | impl TS { | |
112 | pub fn ts() -> Self { | |
113 | Self(0) | |
114 | } | |
115 | } | |
116 | } | |
117 | ||
118 | mod macros { | |
119 | macro_rules! use_self_expand { | |
120 | () => { | |
121 | fn new() -> Foo { | |
122 | Foo {} | |
123 | } | |
124 | }; | |
125 | } | |
126 | ||
127 | struct Foo {} | |
128 | ||
129 | impl Foo { | |
130 | use_self_expand!(); // Should not lint in local macros | |
131 | } | |
132 | ||
133 | #[derive(StructAUseSelf)] // Should not lint in derives | |
134 | struct A; | |
135 | } | |
136 | ||
137 | mod nesting { | |
138 | struct Foo {} | |
139 | impl Foo { | |
140 | fn foo() { | |
141 | #[allow(unused_imports)] | |
142 | use self::Foo; // Can't use Self here | |
143 | struct Bar { | |
144 | foo: Foo, // Foo != Self | |
145 | } | |
146 | ||
147 | impl Bar { | |
148 | fn bar() -> Self { | |
149 | Self { foo: Foo {} } | |
150 | } | |
151 | } | |
152 | ||
153 | // Can't use Self here | |
154 | fn baz() -> Foo { | |
155 | Foo {} | |
156 | } | |
157 | } | |
158 | ||
159 | // Should lint here | |
160 | fn baz() -> Self { | |
161 | Self {} | |
162 | } | |
163 | } | |
164 | ||
165 | enum Enum { | |
166 | A, | |
167 | B(u64), | |
168 | C { field: bool }, | |
169 | } | |
170 | impl Enum { | |
171 | fn method() { | |
172 | #[allow(unused_imports)] | |
173 | use self::Enum::*; // Issue 3425 | |
174 | static STATIC: Enum = Enum::A; // Can't use Self as type | |
175 | } | |
176 | ||
177 | fn method2() { | |
178 | let _ = Self::B(42); | |
179 | let _ = Self::C { field: true }; | |
180 | let _ = Self::A; | |
181 | } | |
182 | } | |
183 | } | |
184 | ||
185 | mod issue3410 { | |
186 | ||
187 | struct A; | |
188 | struct B; | |
189 | ||
190 | trait Trait<T> { | |
191 | fn a(v: T) -> Self; | |
192 | } | |
193 | ||
194 | impl Trait<Vec<A>> for Vec<B> { | |
195 | fn a(_: Vec<A>) -> Self { | |
196 | unimplemented!() | |
197 | } | |
198 | } | |
199 | ||
200 | impl<T> Trait<Vec<A>> for Vec<T> | |
201 | where | |
202 | T: Trait<B>, | |
203 | { | |
204 | fn a(v: Vec<A>) -> Self { | |
205 | <Vec<B>>::a(v).into_iter().map(Trait::a).collect() | |
206 | } | |
207 | } | |
208 | } | |
209 | ||
210 | #[allow(clippy::no_effect, path_statements)] | |
211 | mod rustfix { | |
212 | mod nested { | |
213 | pub struct A {} | |
214 | } | |
215 | ||
216 | impl nested::A { | |
217 | const A: bool = true; | |
218 | ||
219 | fn fun_1() {} | |
220 | ||
221 | fn fun_2() { | |
222 | Self::fun_1(); | |
223 | Self::A; | |
224 | ||
225 | Self {}; | |
226 | } | |
227 | } | |
228 | } | |
229 | ||
230 | mod issue3567 { | |
231 | struct TestStruct {} | |
232 | impl TestStruct { | |
233 | fn from_something() -> Self { | |
234 | Self {} | |
235 | } | |
236 | } | |
237 | ||
238 | trait Test { | |
239 | fn test() -> TestStruct; | |
240 | } | |
241 | ||
242 | impl Test for TestStruct { | |
243 | fn test() -> TestStruct { | |
244 | Self::from_something() | |
245 | } | |
246 | } | |
247 | } | |
248 | ||
249 | mod paths_created_by_lowering { | |
250 | use std::ops::Range; | |
251 | ||
252 | struct S {} | |
253 | ||
254 | impl S { | |
255 | const A: usize = 0; | |
256 | const B: usize = 1; | |
257 | ||
258 | async fn g() -> Self { | |
259 | Self {} | |
260 | } | |
261 | ||
262 | fn f<'a>(&self, p: &'a [u8]) -> &'a [u8] { | |
263 | &p[Self::A..Self::B] | |
264 | } | |
265 | } | |
266 | ||
267 | trait T { | |
268 | fn f<'a>(&self, p: &'a [u8]) -> &'a [u8]; | |
269 | } | |
270 | ||
271 | impl T for Range<u8> { | |
272 | fn f<'a>(&self, p: &'a [u8]) -> &'a [u8] { | |
273 | &p[0..1] | |
274 | } | |
275 | } | |
276 | } | |
277 | ||
278 | // reused from #1997 | |
279 | mod generics { | |
280 | struct Foo<T> { | |
281 | value: T, | |
282 | } | |
283 | ||
284 | impl<T> Foo<T> { | |
285 | // `Self` is applicable here | |
286 | fn foo(value: T) -> Self { | |
287 | Self { value } | |
288 | } | |
289 | ||
290 | // `Cannot` use `Self` as a return type as the generic types are different | |
291 | fn bar(value: i32) -> Foo<i32> { | |
292 | Foo { value } | |
293 | } | |
294 | } | |
295 | } | |
296 | ||
297 | mod issue4140 { | |
298 | pub struct Error<From, To> { | |
299 | _from: From, | |
300 | _too: To, | |
301 | } | |
302 | ||
303 | pub trait From<T> { | |
304 | type From; | |
305 | type To; | |
306 | ||
307 | fn from(value: T) -> Self; | |
308 | } | |
309 | ||
310 | pub trait TryFrom<T> | |
311 | where | |
312 | Self: Sized, | |
313 | { | |
314 | type From; | |
315 | type To; | |
316 | ||
317 | fn try_from(value: T) -> Result<Self, Error<Self::From, Self::To>>; | |
318 | } | |
319 | ||
320 | // FIXME: Suggested fix results in infinite recursion. | |
321 | // impl<F, T> TryFrom<F> for T | |
322 | // where | |
323 | // T: From<F>, | |
324 | // { | |
325 | // type From = Self::From; | |
326 | // type To = Self::To; | |
327 | ||
328 | // fn try_from(value: F) -> Result<Self, Error<Self::From, Self::To>> { | |
329 | // Ok(From::from(value)) | |
330 | // } | |
331 | // } | |
332 | ||
333 | impl From<bool> for i64 { | |
334 | type From = bool; | |
335 | type To = Self; | |
336 | ||
337 | fn from(value: bool) -> Self { | |
338 | if value { 100 } else { 0 } | |
339 | } | |
340 | } | |
341 | } | |
342 | ||
343 | mod issue2843 { | |
344 | trait Foo { | |
345 | type Bar; | |
346 | } | |
347 | ||
348 | impl Foo for usize { | |
349 | type Bar = u8; | |
350 | } | |
351 | ||
352 | impl<T: Foo> Foo for Option<T> { | |
353 | type Bar = Option<T::Bar>; | |
354 | } | |
355 | } | |
356 | ||
357 | mod issue3859 { | |
358 | pub struct Foo; | |
359 | pub struct Bar([usize; 3]); | |
360 | ||
361 | impl Foo { | |
362 | pub const BAR: usize = 3; | |
363 | ||
364 | pub fn foo() { | |
365 | const _X: usize = Foo::BAR; | |
366 | // const _Y: usize = Self::BAR; | |
367 | } | |
368 | } | |
369 | } | |
370 | ||
371 | mod issue4305 { | |
372 | trait Foo: 'static {} | |
373 | ||
374 | struct Bar; | |
375 | ||
376 | impl Foo for Bar {} | |
377 | ||
378 | impl<T: Foo> From<T> for Box<dyn Foo> { | |
379 | fn from(t: T) -> Self { | |
380 | Box::new(t) | |
381 | } | |
382 | } | |
383 | } | |
384 | ||
385 | mod lint_at_item_level { | |
386 | struct Foo {} | |
387 | ||
388 | #[allow(clippy::use_self)] | |
389 | impl Foo { | |
390 | fn new() -> Foo { | |
391 | Foo {} | |
392 | } | |
393 | } | |
394 | ||
395 | #[allow(clippy::use_self)] | |
396 | impl Default for Foo { | |
397 | fn default() -> Foo { | |
398 | Foo::new() | |
399 | } | |
400 | } | |
401 | } | |
402 | ||
403 | mod lint_at_impl_item_level { | |
404 | struct Foo {} | |
405 | ||
406 | impl Foo { | |
407 | #[allow(clippy::use_self)] | |
408 | fn new() -> Foo { | |
409 | Foo {} | |
410 | } | |
411 | } | |
412 | ||
413 | impl Default for Foo { | |
414 | #[allow(clippy::use_self)] | |
415 | fn default() -> Foo { | |
416 | Foo::new() | |
417 | } | |
418 | } | |
419 | } | |
420 | ||
421 | mod issue4734 { | |
422 | #[repr(C, packed)] | |
423 | pub struct X { | |
424 | pub x: u32, | |
425 | } | |
426 | ||
427 | impl From<X> for u32 { | |
428 | fn from(c: X) -> Self { | |
429 | unsafe { core::mem::transmute(c) } | |
430 | } | |
431 | } | |
432 | } | |
433 | ||
434 | mod nested_paths { | |
435 | use std::convert::Into; | |
436 | mod submod { | |
437 | pub struct B {} | |
438 | pub struct C {} | |
439 | ||
440 | impl Into<C> for B { | |
441 | fn into(self) -> C { | |
442 | C {} | |
443 | } | |
444 | } | |
445 | } | |
446 | ||
447 | struct A<T> { | |
448 | t: T, | |
449 | } | |
450 | ||
451 | impl<T> A<T> { | |
452 | fn new<V: Into<T>>(v: V) -> Self { | |
453 | Self { t: Into::into(v) } | |
454 | } | |
455 | } | |
456 | ||
457 | impl A<submod::C> { | |
458 | fn test() -> Self { | |
459 | Self::new::<submod::B>(submod::B {}) | |
460 | } | |
461 | } | |
462 | } | |
463 | ||
464 | mod issue6818 { | |
465 | #[derive(serde::Deserialize)] | |
466 | struct A { | |
467 | a: i32, | |
468 | } | |
469 | } | |
17df50a5 XL |
470 | |
471 | mod issue7206 { | |
472 | struct MyStruct<const C: char>; | |
473 | impl From<MyStruct<'a'>> for MyStruct<'b'> { | |
474 | fn from(_s: MyStruct<'a'>) -> Self { | |
475 | Self | |
476 | } | |
477 | } | |
478 | ||
479 | // keep linting non-`Const` generic args | |
480 | struct S<'a> { | |
481 | inner: &'a str, | |
482 | } | |
483 | ||
484 | struct S2<T> { | |
485 | inner: T, | |
486 | } | |
487 | ||
488 | impl<T> S2<T> { | |
489 | fn new() -> Self { | |
490 | unimplemented!(); | |
491 | } | |
492 | } | |
493 | ||
494 | impl<'a> S2<S<'a>> { | |
495 | fn new_again() -> Self { | |
496 | Self::new() | |
497 | } | |
498 | } | |
499 | } | |
136023e0 XL |
500 | |
501 | mod self_is_ty_param { | |
502 | trait Trait { | |
503 | type Type; | |
504 | type Hi; | |
505 | ||
506 | fn test(); | |
507 | } | |
508 | ||
509 | impl<I> Trait for I | |
510 | where | |
511 | I: Iterator, | |
512 | I::Item: Trait, // changing this to Self would require <Self as Iterator> | |
513 | { | |
514 | type Type = I; | |
515 | type Hi = I::Item; | |
516 | ||
517 | fn test() { | |
518 | let _: I::Item; | |
519 | let _: I; // this could lint, but is questionable | |
520 | } | |
521 | } | |
522 | } |