]> git.lizzy.rs Git - rust.git/blob - tests/ui/use_self.fixed
Fix `use_self` false positive on nested functions
[rust.git] / tests / ui / use_self.fixed
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() -> Self {
14             Self {}
15         }
16         fn test() -> Self {
17             Self::new()
18         }
19     }
20
21     impl Default for Foo {
22         fn default() -> Self {
23             Self::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: &Self) -> &Self {
89             p1
90         }
91
92         fn ref_refs<'a>(p1: &'a &'a Self) -> &'a &'a Self {
93             p1
94         }
95
96         fn mut_refs(p1: &mut Self) -> &mut Self {
97             p1
98         }
99
100         fn nested(_p1: Box<Self>, _p2: (&u8, &Self)) {}
101
102         fn vals(_: Self) -> Self {
103             Self::default()
104         }
105     }
106
107     impl Mul for Bad {
108         type Output = Self;
109
110         fn mul(self, rhs: Self) -> Self {
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 = &Self> {
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             Self(0)
218         }
219     }
220 }
221
222 mod macros {
223     macro_rules! use_self_expand {
224         () => {
225             fn new() -> Self {
226                 Self {}
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             use self::Foo; // Can't use Self here
243             struct Bar {
244                 foo: Foo, // Foo != Self
245             }
246
247             impl Bar {
248                 fn bar() -> Self {
249                     Self { foo: Foo {} }
250                 }
251             }
252
253             // Can't use Self here
254             fn baz() -> Foo {
255                 Foo {}
256             }
257         }
258
259         // Should lint here
260         fn baz() -> Self {
261             Self {}
262         }
263     }
264
265     enum Enum {
266         A,
267     }
268     impl Enum {
269         fn method() {
270             #[allow(unused_imports)]
271             use self::Enum::*; // Issue 3425
272             static STATIC: Enum = Enum::A; // Can't use Self as type
273         }
274     }
275 }
276
277 mod issue3410 {
278
279     struct A;
280     struct B;
281
282     trait Trait<T> {
283         fn a(v: T);
284     }
285
286     impl Trait<Vec<A>> for Vec<B> {
287         fn a(_: Vec<A>) {}
288     }
289 }
290
291 #[allow(clippy::no_effect, path_statements)]
292 mod rustfix {
293     mod nested {
294         pub struct A {}
295     }
296
297     impl nested::A {
298         const A: bool = true;
299
300         fn fun_1() {}
301
302         fn fun_2() {
303             Self::fun_1();
304             Self::A;
305
306             Self {};
307         }
308     }
309 }