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