]> git.lizzy.rs Git - rust.git/blob - tests/ui/use_self.rs
Add version = "Two" to rustfmt.toml
[rust.git] / tests / ui / use_self.rs
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() -> Foo {
19             Foo {}
20         }
21         fn test() -> Foo {
22             Foo::new()
23         }
24     }
25
26     impl Default for Foo {
27         fn default() -> Foo {
28             Foo::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: &[Foo]) -> impl Iterator<Item = &Foo> {
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             TS(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() -> Bar {
144                     Bar { 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() -> Foo {
156             Foo {}
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 _ = Enum::B(42);
174             let _ = Enum::C { field: true };
175             let _ = Enum::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             nested::A::fun_1();
218             nested::A::A;
219
220             nested::A {};
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             TestStruct::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() -> S {
254             S {}
255         }
256
257         fn f<'a>(&self, p: &'a [u8]) -> &'a [u8] {
258             &p[S::A..S::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) -> Foo<T> {
282             Foo { 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     impl<F, T> TryFrom<F> for T
316     where
317         T: From<F>,
318     {
319         type From = T::From;
320         type To = T::To;
321
322         fn try_from(value: F) -> Result<Self, Error<Self::From, Self::To>> {
323             Ok(From::from(value))
324         }
325     }
326
327     impl From<bool> for i64 {
328         type From = bool;
329         type To = Self;
330
331         fn from(value: bool) -> Self {
332             if value { 100 } else { 0 }
333         }
334     }
335 }
336
337 mod issue2843 {
338     trait Foo {
339         type Bar;
340     }
341
342     impl Foo for usize {
343         type Bar = u8;
344     }
345
346     impl<T: Foo> Foo for Option<T> {
347         type Bar = Option<T::Bar>;
348     }
349 }
350
351 mod issue3859 {
352     pub struct Foo;
353     pub struct Bar([usize; 3]);
354
355     impl Foo {
356         pub const BAR: usize = 3;
357
358         pub fn foo() {
359             const _X: usize = Foo::BAR;
360             // const _Y: usize = Self::BAR;
361         }
362     }
363 }
364
365 mod issue4305 {
366     trait Foo: 'static {}
367
368     struct Bar;
369
370     impl Foo for Bar {}
371
372     impl<T: Foo> From<T> for Box<dyn Foo> {
373         fn from(t: T) -> Self {
374             Box::new(t)
375         }
376     }
377 }
378
379 mod lint_at_item_level {
380     struct Foo {}
381
382     #[allow(clippy::use_self)]
383     impl Foo {
384         fn new() -> Foo {
385             Foo {}
386         }
387     }
388
389     #[allow(clippy::use_self)]
390     impl Default for Foo {
391         fn default() -> Foo {
392             Foo::new()
393         }
394     }
395 }
396
397 mod lint_at_impl_item_level {
398     struct Foo {}
399
400     impl Foo {
401         #[allow(clippy::use_self)]
402         fn new() -> Foo {
403             Foo {}
404         }
405     }
406
407     impl Default for Foo {
408         #[allow(clippy::use_self)]
409         fn default() -> Foo {
410             Foo::new()
411         }
412     }
413 }
414
415 mod issue4734 {
416     #[repr(C, packed)]
417     pub struct X {
418         pub x: u32,
419     }
420
421     impl From<X> for u32 {
422         fn from(c: X) -> Self {
423             unsafe { core::mem::transmute(c) }
424         }
425     }
426 }
427
428 mod nested_paths {
429     use std::convert::Into;
430     mod submod {
431         pub struct B {}
432         pub struct C {}
433
434         impl Into<C> for B {
435             fn into(self) -> C {
436                 C {}
437             }
438         }
439     }
440
441     struct A<T> {
442         t: T,
443     }
444
445     impl<T> A<T> {
446         fn new<V: Into<T>>(v: V) -> Self {
447             Self { t: Into::into(v) }
448         }
449     }
450
451     impl A<submod::C> {
452         fn test() -> Self {
453             A::new::<submod::B>(submod::B {})
454         }
455     }
456 }