]> git.lizzy.rs Git - rust.git/blob - tests/ui/use_self.rs
Auto merge of #4314 - chansuke:add-negation-to-is_empty, r=flip1995
[rust.git] / tests / ui / use_self.rs
1 // run-rustfix
2
3 #![warn(clippy::use_self)]
4 #![allow(dead_code)]
5 #![allow(clippy::should_implement_trait)]
6
7 fn main() {}
8
9 mod use_self {
10     struct Foo {}
11
12     impl Foo {
13         fn new() -> Foo {
14             Foo {}
15         }
16         fn test() -> Foo {
17             Foo::new()
18         }
19     }
20
21     impl Default for Foo {
22         fn default() -> Foo {
23             Foo::new()
24         }
25     }
26 }
27
28 mod better {
29     struct Foo {}
30
31     impl Foo {
32         fn new() -> Self {
33             Self {}
34         }
35         fn test() -> Self {
36             Self::new()
37         }
38     }
39
40     impl Default for Foo {
41         fn default() -> Self {
42             Self::new()
43         }
44     }
45 }
46
47 mod lifetimes {
48     struct Foo<'a> {
49         foo_str: &'a str,
50     }
51
52     impl<'a> Foo<'a> {
53         // Cannot use `Self` as return type, because the function is actually `fn foo<'b>(s: &'b str) ->
54         // Foo<'b>`
55         fn foo(s: &str) -> Foo {
56             Foo { foo_str: s }
57         }
58         // cannot replace with `Self`, because that's `Foo<'a>`
59         fn bar() -> Foo<'static> {
60             Foo { foo_str: "foo" }
61         }
62
63         // FIXME: the lint does not handle lifetimed struct
64         // `Self` should be applicable here
65         fn clone(&self) -> Foo<'a> {
66             Foo { foo_str: self.foo_str }
67         }
68     }
69 }
70
71 #[allow(clippy::boxed_local)]
72 mod traits {
73
74     use std::ops::Mul;
75
76     trait SelfTrait {
77         fn refs(p1: &Self) -> &Self;
78         fn ref_refs<'a>(p1: &'a &'a Self) -> &'a &'a Self;
79         fn mut_refs(p1: &mut Self) -> &mut Self;
80         fn nested(p1: Box<Self>, p2: (&u8, &Self));
81         fn vals(r: Self) -> Self;
82     }
83
84     #[derive(Default)]
85     struct Bad;
86
87     impl SelfTrait for Bad {
88         fn refs(p1: &Bad) -> &Bad {
89             p1
90         }
91
92         fn ref_refs<'a>(p1: &'a &'a Bad) -> &'a &'a Bad {
93             p1
94         }
95
96         fn mut_refs(p1: &mut Bad) -> &mut Bad {
97             p1
98         }
99
100         fn nested(_p1: Box<Bad>, _p2: (&u8, &Bad)) {}
101
102         fn vals(_: Bad) -> Bad {
103             Bad::default()
104         }
105     }
106
107     impl Mul for Bad {
108         type Output = Bad;
109
110         fn mul(self, rhs: Bad) -> Bad {
111             rhs
112         }
113     }
114
115     #[derive(Default)]
116     struct Good;
117
118     impl SelfTrait for Good {
119         fn refs(p1: &Self) -> &Self {
120             p1
121         }
122
123         fn ref_refs<'a>(p1: &'a &'a Self) -> &'a &'a Self {
124             p1
125         }
126
127         fn mut_refs(p1: &mut Self) -> &mut Self {
128             p1
129         }
130
131         fn nested(_p1: Box<Self>, _p2: (&u8, &Self)) {}
132
133         fn vals(_: Self) -> Self {
134             Self::default()
135         }
136     }
137
138     impl Mul for Good {
139         type Output = Self;
140
141         fn mul(self, rhs: Self) -> Self {
142             rhs
143         }
144     }
145
146     trait NameTrait {
147         fn refs(p1: &u8) -> &u8;
148         fn ref_refs<'a>(p1: &'a &'a u8) -> &'a &'a u8;
149         fn mut_refs(p1: &mut u8) -> &mut u8;
150         fn nested(p1: Box<u8>, p2: (&u8, &u8));
151         fn vals(p1: u8) -> u8;
152     }
153
154     // Using `Self` instead of the type name is OK
155     impl NameTrait for u8 {
156         fn refs(p1: &Self) -> &Self {
157             p1
158         }
159
160         fn ref_refs<'a>(p1: &'a &'a Self) -> &'a &'a Self {
161             p1
162         }
163
164         fn mut_refs(p1: &mut Self) -> &mut Self {
165             p1
166         }
167
168         fn nested(_p1: Box<Self>, _p2: (&Self, &Self)) {}
169
170         fn vals(_: Self) -> Self {
171             Self::default()
172         }
173     }
174
175     // Check that self arg isn't linted
176     impl Clone for Good {
177         fn clone(&self) -> Self {
178             // Note: Not linted and it wouldn't be valid
179             // because "can't use `Self` as a constructor`"
180             Good
181         }
182     }
183 }
184
185 mod issue2894 {
186     trait IntoBytes {
187         fn into_bytes(&self) -> Vec<u8>;
188     }
189
190     // This should not be linted
191     impl IntoBytes for u8 {
192         fn into_bytes(&self) -> Vec<u8> {
193             vec![*self]
194         }
195     }
196 }
197
198 mod existential {
199     struct Foo;
200
201     impl Foo {
202         fn bad(foos: &[Self]) -> impl Iterator<Item = &Foo> {
203             foos.iter()
204         }
205
206         fn good(foos: &[Self]) -> impl Iterator<Item = &Self> {
207             foos.iter()
208         }
209     }
210 }
211
212 mod tuple_structs {
213     pub struct TS(i32);
214
215     impl TS {
216         pub fn ts() -> Self {
217             TS(0)
218         }
219     }
220 }
221
222 mod macros {
223     macro_rules! use_self_expand {
224         () => {
225             fn new() -> Foo {
226                 Foo {}
227             }
228         };
229     }
230
231     struct Foo {}
232
233     impl Foo {
234         use_self_expand!(); // Should lint in local macros
235     }
236 }
237
238 mod nesting {
239     struct Foo {}
240     impl Foo {
241         fn foo() {
242             #[allow(unused_imports)]
243             use self::Foo; // Can't use Self here
244             struct Bar {
245                 foo: Foo, // Foo != Self
246             }
247
248             impl Bar {
249                 fn bar() -> Bar {
250                     Bar { foo: Foo {} }
251                 }
252             }
253
254             // Can't use Self here
255             fn baz() -> Foo {
256                 Foo {}
257             }
258         }
259
260         // Should lint here
261         fn baz() -> Foo {
262             Foo {}
263         }
264     }
265
266     enum Enum {
267         A,
268         B(u64),
269         C { field: bool },
270     }
271     impl Enum {
272         fn method() {
273             #[allow(unused_imports)]
274             use self::Enum::*; // Issue 3425
275             static STATIC: Enum = Enum::A; // Can't use Self as type
276         }
277
278         fn method2() {
279             let _ = Enum::B(42);
280             let _ = Enum::C { field: true };
281             let _ = Enum::A;
282         }
283     }
284 }
285
286 mod issue3410 {
287
288     struct A;
289     struct B;
290
291     trait Trait<T> {
292         fn a(v: T);
293     }
294
295     impl Trait<Vec<A>> for Vec<B> {
296         fn a(_: Vec<A>) {}
297     }
298 }
299
300 #[allow(clippy::no_effect, path_statements)]
301 mod rustfix {
302     mod nested {
303         pub struct A {}
304     }
305
306     impl nested::A {
307         const A: bool = true;
308
309         fn fun_1() {}
310
311         fn fun_2() {
312             nested::A::fun_1();
313             nested::A::A;
314
315             nested::A {};
316         }
317     }
318 }