about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2022-03-02 19:31:22 +0000
committerbors <bors@rust-lang.org>2022-03-02 19:31:22 +0000
commit2e40dc81b796ac063be1106b3e4a7e51dd54e85e (patch)
tree67e8f5fbc2e8aadeca44636701a4e79968eee8a9
parent27869d6d46644e4910e539e491c822a296a8902c (diff)
parent914ae1e8490c4d6e34dc090cad30303b95d44bb7 (diff)
downloadrust-2e40dc81b796ac063be1106b3e4a7e51dd54e85e.tar.gz
rust-2e40dc81b796ac063be1106b3e4a7e51dd54e85e.zip
Auto merge of #8456 - ebobrow:use_self_pat, r=llogiq
check `use_self` in `pat`

fixes #6955

changelog: check `use_self` in `pat`
-rw-r--r--clippy_lints/src/use_self.rs19
-rw-r--r--tests/ui/use_self.fixed25
-rw-r--r--tests/ui/use_self.rs25
-rw-r--r--tests/ui/use_self.stderr20
4 files changed, 85 insertions, 4 deletions
diff --git a/clippy_lints/src/use_self.rs b/clippy_lints/src/use_self.rs
index 80164c59ba7..09d671e1118 100644
--- a/clippy_lints/src/use_self.rs
+++ b/clippy_lints/src/use_self.rs
@@ -9,7 +9,8 @@ use rustc_hir::{
     def::{CtorOf, DefKind, Res},
     def_id::LocalDefId,
     intravisit::{walk_inf, walk_ty, Visitor},
-    Expr, ExprKind, FnRetTy, FnSig, GenericArg, HirId, Impl, ImplItemKind, Item, ItemKind, Path, QPath, TyKind,
+    Expr, ExprKind, FnRetTy, FnSig, GenericArg, HirId, Impl, ImplItemKind, Item, ItemKind, Pat, PatKind, Path, QPath,
+    TyKind,
 };
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_semver::RustcVersion;
@@ -252,6 +253,22 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf {
         }
     }
 
+    fn check_pat(&mut self, cx: &LateContext<'_>, pat: &Pat<'_>) {
+        if_chain! {
+            if !pat.span.from_expansion();
+            if meets_msrv(self.msrv.as_ref(), &msrvs::TYPE_ALIAS_ENUM_VARIANTS);
+            if let Some(&StackItem::Check { impl_id, .. }) = self.stack.last();
+            if let PatKind::Path(QPath::Resolved(_, path)) = pat.kind;
+            if !matches!(path.res, Res::SelfTy { .. } | Res::Def(DefKind::TyParam, _));
+            if cx.typeck_results().pat_ty(pat) == cx.tcx.type_of(impl_id);
+            if let [first, ..] = path.segments;
+            if let Some(hir_id) = first.hir_id;
+            then {
+                span_lint(cx, cx.tcx.hir().span(hir_id));
+            }
+        }
+    }
+
     extract_msrv_attr!(LateContext);
 }
 
diff --git a/tests/ui/use_self.fixed b/tests/ui/use_self.fixed
index 4e33e343ce0..9d216f56ae6 100644
--- a/tests/ui/use_self.fixed
+++ b/tests/ui/use_self.fixed
@@ -2,7 +2,7 @@
 // aux-build:proc_macro_derive.rs
 
 #![warn(clippy::use_self)]
-#![allow(dead_code)]
+#![allow(dead_code, unreachable_code)]
 #![allow(
     clippy::should_implement_trait,
     clippy::upper_case_acronyms,
@@ -519,3 +519,26 @@ mod self_is_ty_param {
         }
     }
 }
+
+mod use_self_in_pat {
+    enum Foo {
+        Bar,
+        Baz,
+    }
+
+    impl Foo {
+        fn do_stuff(self) {
+            match self {
+                Self::Bar => unimplemented!(),
+                Self::Baz => unimplemented!(),
+            }
+            match Some(1) {
+                Some(_) => unimplemented!(),
+                None => unimplemented!(),
+            }
+            if let Self::Bar = self {
+                unimplemented!()
+            }
+        }
+    }
+}
diff --git a/tests/ui/use_self.rs b/tests/ui/use_self.rs
index 7b621ff9bca..5f604fe25e4 100644
--- a/tests/ui/use_self.rs
+++ b/tests/ui/use_self.rs
@@ -2,7 +2,7 @@
 // aux-build:proc_macro_derive.rs
 
 #![warn(clippy::use_self)]
-#![allow(dead_code)]
+#![allow(dead_code, unreachable_code)]
 #![allow(
     clippy::should_implement_trait,
     clippy::upper_case_acronyms,
@@ -519,3 +519,26 @@ mod self_is_ty_param {
         }
     }
 }
+
+mod use_self_in_pat {
+    enum Foo {
+        Bar,
+        Baz,
+    }
+
+    impl Foo {
+        fn do_stuff(self) {
+            match self {
+                Foo::Bar => unimplemented!(),
+                Foo::Baz => unimplemented!(),
+            }
+            match Some(1) {
+                Some(_) => unimplemented!(),
+                None => unimplemented!(),
+            }
+            if let Foo::Bar = self {
+                unimplemented!()
+            }
+        }
+    }
+}
diff --git a/tests/ui/use_self.stderr b/tests/ui/use_self.stderr
index ecb78b3f972..34d98618253 100644
--- a/tests/ui/use_self.stderr
+++ b/tests/ui/use_self.stderr
@@ -168,5 +168,23 @@ error: unnecessary structure name repetition
 LL |             S2::new()
    |             ^^ help: use the applicable keyword: `Self`
 
-error: aborting due to 28 previous errors
+error: unnecessary structure name repetition
+  --> $DIR/use_self.rs:532:17
+   |
+LL |                 Foo::Bar => unimplemented!(),
+   |                 ^^^ help: use the applicable keyword: `Self`
+
+error: unnecessary structure name repetition
+  --> $DIR/use_self.rs:533:17
+   |
+LL |                 Foo::Baz => unimplemented!(),
+   |                 ^^^ help: use the applicable keyword: `Self`
+
+error: unnecessary structure name repetition
+  --> $DIR/use_self.rs:539:20
+   |
+LL |             if let Foo::Bar = self {
+   |                    ^^^ help: use the applicable keyword: `Self`
+
+error: aborting due to 31 previous errors