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