about summary refs log tree commit diff
diff options
context:
space:
mode:
authorWilco Kusee <wilcokusee@gmail.com>2018-12-27 17:27:42 +0100
committerWilco Kusee <wilcokusee@gmail.com>2018-12-30 08:23:38 +0100
commitab42ba4f54d2be62f271bad44f065d1814d17d4a (patch)
treeba8d624b85c0c21c88d597469d394bc4bc513dba
parent0f3dcdc3aad5527049c6cfcfae8bd3d697c26447 (diff)
downloadrust-ab42ba4f54d2be62f271bad44f065d1814d17d4a.tar.gz
rust-ab42ba4f54d2be62f271bad44f065d1814d17d4a.zip
Implement use_self for tuple structs
-rw-r--r--clippy_lints/src/use_self.rs15
-rw-r--r--tests/ui/use_self.rs10
-rw-r--r--tests/ui/use_self.stderr8
3 files changed, 27 insertions, 6 deletions
diff --git a/clippy_lints/src/use_self.rs b/clippy_lints/src/use_self.rs
index d08a8931419..fb71352a795 100644
--- a/clippy_lints/src/use_self.rs
+++ b/clippy_lints/src/use_self.rs
@@ -9,6 +9,7 @@
 
 use crate::utils::{in_macro, span_lint_and_sugg};
 use if_chain::if_chain;
+use rustc::hir::def::{CtorKind, Def};
 use rustc::hir::intravisit::{walk_path, walk_ty, NestedVisitorMap, Visitor};
 use rustc::hir::*;
 use rustc::lint::{LateContext, LateLintPass, LintArray, LintPass};
@@ -30,8 +31,7 @@ use syntax_pos::symbol::keywords::SelfUpper;
 /// - False positive when using associated types (#2843)
 /// - False positives in some situations when using generics (#3410)
 /// - False positive when type from outer function can't be used (#3463)
-/// - Does not diagnose tuple structs (#3498)
-/// - Does not trigger in lifetimed struct
+/// - Does not trigger in lifetimed structs
 ///
 /// **Example:**
 /// ```rust
@@ -232,10 +232,15 @@ struct UseSelfVisitor<'a, 'tcx: 'a> {
 
 impl<'a, 'tcx> Visitor<'tcx> for UseSelfVisitor<'a, 'tcx> {
     fn visit_path(&mut self, path: &'tcx Path, _id: HirId) {
-        if self.item_path.def == path.def && path.segments.last().expect(SEGMENTS_MSG).ident.name != SelfUpper.name() {
-            span_use_self_lint(self.cx, path);
+        if path.segments.last().expect(SEGMENTS_MSG).ident.name != SelfUpper.name() {
+            if self.item_path.def == path.def {
+                span_use_self_lint(self.cx, path);
+            } else if let Def::StructCtor(ctor_did, CtorKind::Fn) = path.def {
+                if self.item_path.def.opt_def_id() == self.cx.tcx.parent_def_id(ctor_did) {
+                    span_use_self_lint(self.cx, path);
+                }
+            }
         }
-
         walk_path(self, path);
     }
 
diff --git a/tests/ui/use_self.rs b/tests/ui/use_self.rs
index 561d2418228..450278f2ed9 100644
--- a/tests/ui/use_self.rs
+++ b/tests/ui/use_self.rs
@@ -216,6 +216,16 @@ mod existential {
     }
 }
 
+mod tuple_structs {
+    pub struct TS(i32);
+
+    impl TS {
+        pub fn ts() -> Self {
+            TS(0)
+        }
+    }
+}
+
 mod issue3410 {
 
     struct A;
diff --git a/tests/ui/use_self.stderr b/tests/ui/use_self.stderr
index bb81ad79900..7ef4737dc69 100644
--- a/tests/ui/use_self.stderr
+++ b/tests/ui/use_self.stderr
@@ -126,5 +126,11 @@ error: unnecessary structure name repetition
 LL |         fn bad(foos: &[Self]) -> impl Iterator<Item = &Foo> {
    |                                                        ^^^ help: use the applicable keyword: `Self`
 
-error: aborting due to 21 previous errors
+error: unnecessary structure name repetition
+   --> $DIR/use_self.rs:224:13
+    |
+224 |             TS(0)
+    |             ^^ help: use the applicable keyword: `Self`
+
+error: aborting due to 22 previous errors