diff --git a/clippy_lints/src/use_self.rs b/clippy_lints/src/use_self.rs index b1e46e17f13e..b8c970d376ef 100644 --- a/clippy_lints/src/use_self.rs +++ b/clippy_lints/src/use_self.rs @@ -46,6 +46,8 @@ impl LintPass for UseSelf { } } +const SEGMENTS_MSG: &str = "segments should be composed of at least 1 element"; + impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UseSelf { fn check_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx Item) { if in_macro(item.span) { @@ -54,6 +56,9 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UseSelf { if_let_chain!([ let ItemImpl(.., ref item_type, ref refs) = item.node, let Ty_::TyPath(QPath::Resolved(_, ref item_path)) = item_type.node, + let PathParameters::AngleBracketedParameters(ref param_data) + = item_path.segments.last().expect(SEGMENTS_MSG).parameters, + param_data.lifetimes.len() == 0, ], { let visitor = &mut UseSelfVisitor { item_path: item_path, @@ -76,12 +81,10 @@ impl<'a, 'tcx> Visitor<'tcx> for UseSelfVisitor<'a, 'tcx> { if self.item_path.def == path.def && path.segments .last() - .expect("segments should be composed of at least 1 element") + .expect(SEGMENTS_MSG) .name != SelfType.name() { span_lint_and_then(self.cx, USE_SELF, path.span, "unnecessary structure name repetition", |db| { - db.span_suggestion(path.span, - "use the applicable keyword", - "Self".to_owned()); + db.span_suggestion(path.span, "use the applicable keyword", "Self".to_owned()); }); } diff --git a/tests/ui/methods.stderr b/tests/ui/methods.stderr index 65975c5177c4..8570dccd0feb 100644 --- a/tests/ui/methods.stderr +++ b/tests/ui/methods.stderr @@ -78,24 +78,6 @@ error: methods called `new` usually return `Self` | = note: `-D new-ret-no-self` implied by `-D warnings` -error: unnecessary structure name repetition - --> $DIR/methods.rs:40:35 - | -40 | pub fn new<'b>(s: &'b str) -> Lt<'b> { unimplemented!() } - | ^^^^^^ help: use the applicable keyword: `Self` - -error: unnecessary structure name repetition - --> $DIR/methods.rs:49:28 - | -49 | pub fn new(s: &str) -> Lt2 { unimplemented!() } - | ^^^ help: use the applicable keyword: `Self` - -error: unnecessary structure name repetition - --> $DIR/methods.rs:58:21 - | -58 | pub fn new() -> Lt3<'static> { unimplemented!() } - | ^^^^^^^^^^^^ help: use the applicable keyword: `Self` - error: unnecessary structure name repetition --> $DIR/methods.rs:74:24 | @@ -730,5 +712,5 @@ error: called `cloned().collect()` on a slice to create a `Vec`. Calling `to_vec | = note: `-D iter-cloned-collect` implied by `-D warnings` -error: aborting due to 106 previous errors +error: aborting due to 103 previous errors diff --git a/tests/ui/use_self.rs b/tests/ui/use_self.rs index 40cef1a9362a..14e31aae8ee5 100644 --- a/tests/ui/use_self.rs +++ b/tests/ui/use_self.rs @@ -2,6 +2,7 @@ #![plugin(clippy)] #![warn(use_self)] #![allow(dead_code)] +#![allow(should_implement_trait)] fn main() {} @@ -43,3 +44,25 @@ mod better { } } } + +//todo the lint does not handle lifetimed struct +//the following module should trigger the lint on the third method only +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"} + } + + // `Self` is applicable here + fn clone(&self) -> Foo<'a> { + Foo {foo_str: self.foo_str} + } + } +} diff --git a/tests/ui/use_self.stderr b/tests/ui/use_self.stderr index 0cbd574b5064..bfd334335d88 100644 --- a/tests/ui/use_self.stderr +++ b/tests/ui/use_self.stderr @@ -1,39 +1,39 @@ error: unnecessary structure name repetition - --> $DIR/use_self.rs:13:21 + --> $DIR/use_self.rs:14:21 | -13 | fn new() -> Foo { +14 | fn new() -> Foo { | ^^^ help: use the applicable keyword: `Self` | = note: `-D use-self` implied by `-D warnings` error: unnecessary structure name repetition - --> $DIR/use_self.rs:14:13 + --> $DIR/use_self.rs:15:13 | -14 | Foo {} +15 | Foo {} | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> $DIR/use_self.rs:16:22 + --> $DIR/use_self.rs:17:22 | -16 | fn test() -> Foo { +17 | fn test() -> Foo { | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> $DIR/use_self.rs:17:13 + --> $DIR/use_self.rs:18:13 | -17 | Foo::new() +18 | Foo::new() | ^^^^^^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> $DIR/use_self.rs:22:25 + --> $DIR/use_self.rs:23:25 | -22 | fn default() -> Foo { +23 | fn default() -> Foo { | ^^^ help: use the applicable keyword: `Self` error: unnecessary structure name repetition - --> $DIR/use_self.rs:23:13 + --> $DIR/use_self.rs:24:13 | -23 | Foo::new() +24 | Foo::new() | ^^^^^^^^ help: use the applicable keyword: `Self` error: aborting due to 6 previous errors