check use_self in pat

This commit is contained in:
Elliot Bobrow 2022-02-21 14:38:22 -08:00
parent 9e605ef80f
commit 914ae1e849
4 changed files with 85 additions and 4 deletions

View File

@ -9,7 +9,8 @@
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 @@ fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
}
}
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);
}

View File

@ -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!()
}
}
}
}

View File

@ -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 @@ fn test() {
}
}
}
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!()
}
}
}
}

View File

@ -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