]> git.lizzy.rs Git - rust.git/blob - tests/ui/use_self.fixed
wrong_self_convention: `to_` respects `Copy` types
[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     #[allow(clippy::wrong_self_convention)]
83     impl IntoBytes for u8 {
84         fn to_bytes(&self) -> Vec<u8> {
85             vec![*self]
86         }
87     }
88 }
89
90 mod existential {
91     struct Foo;
92
93     impl Foo {
94         fn bad(foos: &[Self]) -> impl Iterator<Item = &Self> {
95             foos.iter()
96         }
97
98         fn good(foos: &[Self]) -> impl Iterator<Item = &Self> {
99             foos.iter()
100         }
101     }
102 }
103
104 mod tuple_structs {
105     pub struct TS(i32);
106
107     impl TS {
108         pub fn ts() -> Self {
109             Self(0)
110         }
111     }
112 }
113
114 mod macros {
115     macro_rules! use_self_expand {
116         () => {
117             fn new() -> Foo {
118                 Foo {}
119             }
120         };
121     }
122
123     struct Foo {}
124
125     impl Foo {
126         use_self_expand!(); // Should not lint in local macros
127     }
128
129     #[derive(StructAUseSelf)] // Should not lint in derives
130     struct A;
131 }
132
133 mod nesting {
134     struct Foo {}
135     impl Foo {
136         fn foo() {
137             #[allow(unused_imports)]
138             use self::Foo; // Can't use Self here
139             struct Bar {
140                 foo: Foo, // Foo != Self
141             }
142
143             impl Bar {
144                 fn bar() -> Self {
145                     Self { foo: Foo {} }
146                 }
147             }
148
149             // Can't use Self here
150             fn baz() -> Foo {
151                 Foo {}
152             }
153         }
154
155         // Should lint here
156         fn baz() -> Self {
157             Self {}
158         }
159     }
160
161     enum Enum {
162         A,
163         B(u64),
164         C { field: bool },
165     }
166     impl Enum {
167         fn method() {
168             #[allow(unused_imports)]
169             use self::Enum::*; // Issue 3425
170             static STATIC: Enum = Enum::A; // Can't use Self as type
171         }
172
173         fn method2() {
174             let _ = Self::B(42);
175             let _ = Self::C { field: true };
176             let _ = Self::A;
177         }
178     }
179 }
180
181 mod issue3410 {
182
183     struct A;
184     struct B;
185
186     trait Trait<T> {
187         fn a(v: T) -> Self;
188     }
189
190     impl Trait<Vec<A>> for Vec<B> {
191         fn a(_: Vec<A>) -> Self {
192             unimplemented!()
193         }
194     }
195
196     impl<T> Trait<Vec<A>> for Vec<T>
197     where
198         T: Trait<B>,
199     {
200         fn a(v: Vec<A>) -> Self {
201             <Vec<B>>::a(v).into_iter().map(Trait::a).collect()
202         }
203     }
204 }
205
206 #[allow(clippy::no_effect, path_statements)]
207 mod rustfix {
208     mod nested {
209         pub struct A {}
210     }
211
212     impl nested::A {
213         const A: bool = true;
214
215         fn fun_1() {}
216
217         fn fun_2() {
218             Self::fun_1();
219             Self::A;
220
221             Self {};
222         }
223     }
224 }
225
226 mod issue3567 {
227     struct TestStruct {}
228     impl TestStruct {
229         fn from_something() -> Self {
230             Self {}
231         }
232     }
233
234     trait Test {
235         fn test() -> TestStruct;
236     }
237
238     impl Test for TestStruct {
239         fn test() -> TestStruct {
240             Self::from_something()
241         }
242     }
243 }
244
245 mod paths_created_by_lowering {
246     use std::ops::Range;
247
248     struct S {}
249
250     impl S {
251         const A: usize = 0;
252         const B: usize = 1;
253
254         async fn g() -> Self {
255             Self {}
256         }
257
258         fn f<'a>(&self, p: &'a [u8]) -> &'a [u8] {
259             &p[Self::A..Self::B]
260         }
261     }
262
263     trait T {
264         fn f<'a>(&self, p: &'a [u8]) -> &'a [u8];
265     }
266
267     impl T for Range<u8> {
268         fn f<'a>(&self, p: &'a [u8]) -> &'a [u8] {
269             &p[0..1]
270         }
271     }
272 }
273
274 // reused from #1997
275 mod generics {
276     struct Foo<T> {
277         value: T,
278     }
279
280     impl<T> Foo<T> {
281         // `Self` is applicable here
282         fn foo(value: T) -> Self {
283             Self { value }
284         }
285
286         // `Cannot` use `Self` as a return type as the generic types are different
287         fn bar(value: i32) -> Foo<i32> {
288             Foo { value }
289         }
290     }
291 }
292
293 mod issue4140 {
294     pub struct Error<From, To> {
295         _from: From,
296         _too: To,
297     }
298
299     pub trait From<T> {
300         type From;
301         type To;
302
303         fn from(value: T) -> Self;
304     }
305
306     pub trait TryFrom<T>
307     where
308         Self: Sized,
309     {
310         type From;
311         type To;
312
313         fn try_from(value: T) -> Result<Self, Error<Self::From, Self::To>>;
314     }
315
316     impl<F, T> TryFrom<F> for T
317     where
318         T: From<F>,
319     {
320         type From = Self;
321         type To = Self;
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 }