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