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