about summary refs log tree commit diff
diff options
context:
space:
mode:
authorWilco Kusee <wilcokusee@gmail.com>2019-01-06 15:05:04 +0100
committerWilco Kusee <wilcokusee@gmail.com>2019-01-06 15:34:36 +0100
commitff191a808e563d36b4c8bedbd2a67aa44156faf9 (patch)
tree98a65593155573f12b42a3de134817476a4f49c1
parentc63b6349b44019146cc2edcef8141692891b9401 (diff)
downloadrust-ff191a808e563d36b4c8bedbd2a67aa44156faf9.tar.gz
rust-ff191a808e563d36b4c8bedbd2a67aa44156faf9.zip
Restrict use_self on nested items
-rw-r--r--clippy_lints/src/use_self.rs16
-rw-r--r--tests/ui/use_self.rs33
2 files changed, 34 insertions, 15 deletions
diff --git a/clippy_lints/src/use_self.rs b/clippy_lints/src/use_self.rs
index aa4302e12a7..e3e175a17c7 100644
--- a/clippy_lints/src/use_self.rs
+++ b/clippy_lints/src/use_self.rs
@@ -10,13 +10,12 @@
 use crate::utils::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::intravisit::{walk_item, walk_path, walk_ty, NestedVisitorMap, Visitor};
 use rustc::hir::*;
 use rustc::lint::{in_external_macro, LateContext, LateLintPass, LintArray, LintContext, LintPass};
 use rustc::ty;
 use rustc::{declare_tool_lint, lint_array};
 use rustc_errors::Applicability;
-use syntax::ast::NodeId;
 use syntax_pos::symbol::keywords::SelfUpper;
 
 /// **What it does:** Checks for unnecessary repetition of structure name when a
@@ -242,8 +241,17 @@ impl<'a, 'tcx> Visitor<'tcx> for UseSelfVisitor<'a, 'tcx> {
         walk_path(self, path);
     }
 
-    fn visit_use(&mut self, _path: &'tcx Path, _id: NodeId, _hir_id: HirId) {
-        // Don't check use statements
+    fn visit_item(&mut self, item: &'tcx Item) {
+        match item.node {
+            ItemKind::Use(..)
+            | ItemKind::Static(..)
+            | ItemKind::Enum(..)
+            | ItemKind::Struct(..)
+            | ItemKind::Union(..) => {
+                // Don't check statements that shadow `Self` or where `Self` can't be used
+            },
+            _ => walk_item(self, item),
+        }
     }
 
     fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'tcx> {
diff --git a/tests/ui/use_self.rs b/tests/ui/use_self.rs
index a01cb3e7021..f3bd4a05005 100644
--- a/tests/ui/use_self.rs
+++ b/tests/ui/use_self.rs
@@ -242,6 +242,28 @@ mod macros {
     }
 }
 
+mod nesting {
+    struct Foo {}
+    impl Foo {
+        fn foo() {
+            use self::Foo; // Can't use Self here
+            struct Bar {
+                foo: Foo, // Foo != Self
+            }
+        }
+    }
+
+    enum Enum {
+        A,
+    }
+    impl Enum {
+        fn method() {
+            use self::Enum::*;
+            static STATIC: Enum = Enum::A; // Can't use Self as type
+        }
+    }
+}
+
 mod issue3410 {
 
     struct A;
@@ -255,14 +277,3 @@ mod issue3410 {
         fn a(_: Vec<A>) {}
     }
 }
-
-mod issue3425 {
-    enum Enum {
-        A,
-    }
-    impl Enum {
-        fn a() {
-            use self::Enum::*;
-        }
-    }
-}