Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 7 additions & 4 deletions clippy_lints/src/use_self.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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,
Expand All @@ -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());
});
}

Expand Down
20 changes: 1 addition & 19 deletions tests/ui/methods.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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
|
Expand Down Expand Up @@ -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

23 changes: 23 additions & 0 deletions tests/ui/use_self.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#![plugin(clippy)]
#![warn(use_self)]
#![allow(dead_code)]
#![allow(should_implement_trait)]


fn main() {}
Expand Down Expand Up @@ -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}
}
}
}
24 changes: 12 additions & 12 deletions tests/ui/use_self.stderr
Original file line number Diff line number Diff line change
@@ -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
Expand Down