diff --git a/tests/ui/use_self.fixed b/tests/ui/use_self.fixed new file mode 100644 index 00000000000..5eae9a7a806 --- /dev/null +++ b/tests/ui/use_self.fixed @@ -0,0 +1,299 @@ +// run-rustfix + +#![warn(clippy::use_self)] +#![allow(dead_code)] +#![allow(clippy::should_implement_trait)] + +fn main() {} + +mod use_self { + struct Foo {} + + impl Foo { + fn new() -> Self { + Self {} + } + fn test() -> Self { + Self::new() + } + } + + impl Default for Foo { + fn default() -> Self { + Self::new() + } + } +} + +mod better { + struct Foo {} + + impl Foo { + fn new() -> Self { + Self {} + } + fn test() -> Self { + Self::new() + } + } + + impl Default for Foo { + fn default() -> Self { + Self::new() + } + } +} + +mod lifetimes { + struct Foo<'a> { + foo_str: &'a str, + } + + impl<'a> Foo<'a> { + // Cannot use `Self` as return type, because the function is actually `fn foo<'b>(s: &'b str) -> + // Foo<'b>` + fn foo(s: &str) -> Foo { + Foo { foo_str: s } + } + // cannot replace with `Self`, because that's `Foo<'a>` + fn bar() -> Foo<'static> { + Foo { foo_str: "foo" } + } + + // FIXME: the lint does not handle lifetimed struct + // `Self` should be applicable here + fn clone(&self) -> Foo<'a> { + Foo { foo_str: self.foo_str } + } + } +} + +#[allow(clippy::boxed_local)] +mod traits { + + use std::ops::Mul; + + trait SelfTrait { + fn refs(p1: &Self) -> &Self; + fn ref_refs<'a>(p1: &'a &'a Self) -> &'a &'a Self; + fn mut_refs(p1: &mut Self) -> &mut Self; + fn nested(p1: Box, p2: (&u8, &Self)); + fn vals(r: Self) -> Self; + } + + #[derive(Default)] + struct Bad; + + impl SelfTrait for Bad { + fn refs(p1: &Self) -> &Self { + p1 + } + + fn ref_refs<'a>(p1: &'a &'a Self) -> &'a &'a Self { + p1 + } + + fn mut_refs(p1: &mut Self) -> &mut Self { + p1 + } + + fn nested(_p1: Box, _p2: (&u8, &Self)) {} + + fn vals(_: Self) -> Self { + Self::default() + } + } + + impl Mul for Bad { + type Output = Self; + + fn mul(self, rhs: Self) -> Self { + rhs + } + } + + #[derive(Default)] + struct Good; + + impl SelfTrait for Good { + fn refs(p1: &Self) -> &Self { + p1 + } + + fn ref_refs<'a>(p1: &'a &'a Self) -> &'a &'a Self { + p1 + } + + fn mut_refs(p1: &mut Self) -> &mut Self { + p1 + } + + fn nested(_p1: Box, _p2: (&u8, &Self)) {} + + fn vals(_: Self) -> Self { + Self::default() + } + } + + impl Mul for Good { + type Output = Self; + + fn mul(self, rhs: Self) -> Self { + rhs + } + } + + trait NameTrait { + fn refs(p1: &u8) -> &u8; + fn ref_refs<'a>(p1: &'a &'a u8) -> &'a &'a u8; + fn mut_refs(p1: &mut u8) -> &mut u8; + fn nested(p1: Box, p2: (&u8, &u8)); + fn vals(p1: u8) -> u8; + } + + // Using `Self` instead of the type name is OK + impl NameTrait for u8 { + fn refs(p1: &Self) -> &Self { + p1 + } + + fn ref_refs<'a>(p1: &'a &'a Self) -> &'a &'a Self { + p1 + } + + fn mut_refs(p1: &mut Self) -> &mut Self { + p1 + } + + fn nested(_p1: Box, _p2: (&Self, &Self)) {} + + fn vals(_: Self) -> Self { + Self::default() + } + } + + // Check that self arg isn't linted + impl Clone for Good { + fn clone(&self) -> Self { + // Note: Not linted and it wouldn't be valid + // because "can't use `Self` as a constructor`" + Good + } + } +} + +mod issue2894 { + trait IntoBytes { + fn into_bytes(&self) -> Vec; + } + + // This should not be linted + impl IntoBytes for u8 { + fn into_bytes(&self) -> Vec { + vec![*self] + } + } +} + +mod existential { + struct Foo; + + impl Foo { + fn bad(foos: &[Self]) -> impl Iterator { + foos.iter() + } + + fn good(foos: &[Self]) -> impl Iterator { + foos.iter() + } + } +} + +mod tuple_structs { + pub struct TS(i32); + + impl TS { + pub fn ts() -> Self { + Self(0) + } + } +} + +mod macros { + macro_rules! use_self_expand { + () => { + fn new() -> Self { + Self {} + } + }; + } + + struct Foo {} + + impl Foo { + use_self_expand!(); // Should lint in local macros + } +} + +mod nesting { + struct Foo {} + impl Foo { + fn foo() { + use self::Foo; // Can't use Self here + struct Bar { + foo: Foo, // Foo != Self + } + + impl Bar { + fn bar() -> Self { + Self { foo: Foo {} } + } + } + } + } + + enum Enum { + A, + } + impl Enum { + fn method() { + #[allow(unused_imports)] + use self::Enum::*; // Issue 3425 + static STATIC: Enum = Enum::A; // Can't use Self as type + } + } +} + +mod issue3410 { + + struct A; + struct B; + + trait Trait { + fn a(v: T); + } + + impl Trait> for Vec { + fn a(_: Vec) {} + } +} + +#[allow(clippy::no_effect, path_statements)] +mod rustfix { + mod nested { + pub struct A {} + } + + impl nested::A { + const A: bool = true; + + fn fun_1() {} + + fn fun_2() { + Self::fun_1(); + Self::A; + + Self {}; + } + } +} diff --git a/tests/ui/use_self.rs b/tests/ui/use_self.rs index 0cf406b18ce..8e28bbbeb9c 100644 --- a/tests/ui/use_self.rs +++ b/tests/ui/use_self.rs @@ -1,3 +1,5 @@ +// run-rustfix + #![warn(clippy::use_self)] #![allow(dead_code)] #![allow(clippy::should_implement_trait)] @@ -255,6 +257,7 @@ mod nesting { } impl Enum { fn method() { + #[allow(unused_imports)] use self::Enum::*; // Issue 3425 static STATIC: Enum = Enum::A; // Can't use Self as type } @@ -275,7 +278,7 @@ mod issue3410 { } } -#[allow(clippy::no_effect)] +#[allow(clippy::no_effect, path_statements)] mod rustfix { mod nested { pub struct A {} diff --git a/tests/ui/use_self.stderr b/tests/ui/use_self.stderr index 68ce7221d03..af9e15edb6c 100644 --- a/tests/ui/use_self.stderr +++ b/tests/ui/use_self.stderr @@ -1,5 +1,5 @@ error: unnecessary structure name repetition - --> $DIR/use_self.rs:11:21 + --> $DIR/use_self.rs:13:21 | LL | fn new() -> Foo { | ^^^ help: use the applicable keyword: `Self` @@ -7,133 +7,133 @@ LL | fn new() -> Foo { = note: `-D clippy::use-self` implied by `-D warnings` error: unnecessary structure name repetition - --> $DIR/use_self.rs:12:13 + --> $DIR/use_self.rs:14:13 | LL | Foo {} | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> $DIR/use_self.rs:14:22 + --> $DIR/use_self.rs:16:22 | LL | fn test() -> Foo { | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> $DIR/use_self.rs:15:13 + --> $DIR/use_self.rs:17:13 | LL | Foo::new() | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> $DIR/use_self.rs:20:25 + --> $DIR/use_self.rs:22:25 | LL | fn default() -> Foo { | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> $DIR/use_self.rs:21:13 + --> $DIR/use_self.rs:23:13 | LL | Foo::new() | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> $DIR/use_self.rs:86:22 + --> $DIR/use_self.rs:88:22 | LL | fn refs(p1: &Bad) -> &Bad { | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> $DIR/use_self.rs:86:31 + --> $DIR/use_self.rs:88:31 | LL | fn refs(p1: &Bad) -> &Bad { | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> $DIR/use_self.rs:90:37 + --> $DIR/use_self.rs:92:37 | LL | fn ref_refs<'a>(p1: &'a &'a Bad) -> &'a &'a Bad { | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> $DIR/use_self.rs:90:53 + --> $DIR/use_self.rs:92:53 | LL | fn ref_refs<'a>(p1: &'a &'a Bad) -> &'a &'a Bad { | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> $DIR/use_self.rs:94:30 + --> $DIR/use_self.rs:96:30 | LL | fn mut_refs(p1: &mut Bad) -> &mut Bad { | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> $DIR/use_self.rs:94:43 + --> $DIR/use_self.rs:96:43 | LL | fn mut_refs(p1: &mut Bad) -> &mut Bad { | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> $DIR/use_self.rs:98:28 + --> $DIR/use_self.rs:100:28 | LL | fn nested(_p1: Box, _p2: (&u8, &Bad)) {} | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> $DIR/use_self.rs:98:46 + --> $DIR/use_self.rs:100:46 | LL | fn nested(_p1: Box, _p2: (&u8, &Bad)) {} | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> $DIR/use_self.rs:100:20 + --> $DIR/use_self.rs:102:20 | LL | fn vals(_: Bad) -> Bad { | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> $DIR/use_self.rs:100:28 + --> $DIR/use_self.rs:102:28 | LL | fn vals(_: Bad) -> Bad { | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> $DIR/use_self.rs:101:13 + --> $DIR/use_self.rs:103:13 | LL | Bad::default() | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> $DIR/use_self.rs:106:23 + --> $DIR/use_self.rs:108:23 | LL | type Output = Bad; | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> $DIR/use_self.rs:108:27 + --> $DIR/use_self.rs:110:27 | LL | fn mul(self, rhs: Bad) -> Bad { | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> $DIR/use_self.rs:108:35 + --> $DIR/use_self.rs:110:35 | LL | fn mul(self, rhs: Bad) -> Bad { | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> $DIR/use_self.rs:200:56 + --> $DIR/use_self.rs:202:56 | LL | fn bad(foos: &[Self]) -> impl Iterator { | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> $DIR/use_self.rs:215:13 + --> $DIR/use_self.rs:217:13 | LL | TS(0) | ^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> $DIR/use_self.rs:223:25 + --> $DIR/use_self.rs:225:25 | LL | fn new() -> Foo { | ^^^ help: use the applicable keyword: `Self` @@ -142,7 +142,7 @@ LL | use_self_expand!(); // Should lint in local macros | ------------------- in this macro invocation error: unnecessary structure name repetition - --> $DIR/use_self.rs:224:17 + --> $DIR/use_self.rs:226:17 | LL | Foo {} | ^^^ help: use the applicable keyword: `Self` @@ -151,31 +151,31 @@ LL | use_self_expand!(); // Should lint in local macros | ------------------- in this macro invocation error: unnecessary structure name repetition - --> $DIR/use_self.rs:246:29 + --> $DIR/use_self.rs:248:29 | LL | fn bar() -> Bar { | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> $DIR/use_self.rs:247:21 + --> $DIR/use_self.rs:249:21 | LL | Bar { foo: Foo {} } | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> $DIR/use_self.rs:290:13 + --> $DIR/use_self.rs:293:13 | LL | nested::A::fun_1(); | ^^^^^^^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> $DIR/use_self.rs:291:13 + --> $DIR/use_self.rs:294:13 | LL | nested::A::A; | ^^^^^^^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> $DIR/use_self.rs:293:13 + --> $DIR/use_self.rs:296:13 | LL | nested::A {}; | ^^^^^^^^^ help: use the applicable keyword: `Self`