Skip to content

Commit 38d81f3

Browse files
committed
use_self - lint at impl item level #5078
1 parent 5d91ead commit 38d81f3

File tree

4 files changed

+130
-49
lines changed

4 files changed

+130
-49
lines changed

clippy_lints/src/use_self.rs

+30-37
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use rustc_hir as hir;
44
use rustc_hir::def::DefKind;
55
use rustc_hir::intravisit::{walk_expr, walk_impl_item, walk_ty, NestedVisitorMap, Visitor};
66
use rustc_hir::{
7-
def, Expr, ExprKind, FnDecl, FnRetTy, FnSig, GenericArg, ImplItem, ImplItemKind, Item, ItemKind, Node, Path, QPath,
7+
def, Expr, ExprKind, FnDecl, FnRetTy, FnSig, GenericArg, ImplItem, ImplItemKind, ItemKind, Node, Path, QPath,
88
TyKind,
99
};
1010
use rustc_lint::{LateContext, LateLintPass, LintContext};
@@ -101,7 +101,6 @@ fn truncate_last_segment<'a, 'tcx>(cx: &LateContext<'a, 'tcx>, sp: Span) -> Span
101101

102102
struct ImplVisitor<'a, 'tcx> {
103103
cx: &'a LateContext<'a, 'tcx>,
104-
item: &'tcx Item<'tcx>,
105104
self_ty: Ty<'tcx>,
106105
}
107106

@@ -238,58 +237,52 @@ impl<'a, 'tcx> Visitor<'tcx> for ImplVisitor<'a, 'tcx> {
238237
}
239238
walk_expr(self, expr);
240239
}
241-
242-
fn visit_impl_item(&mut self, ii: &'tcx ImplItem<'tcx>) {
243-
let tcx = self.cx.tcx;
244-
let impl_def_id = tcx.hir().local_def_id(self.item.hir_id);
245-
let impl_trait_ref = tcx.impl_trait_ref(impl_def_id);
246-
if_chain! {
247-
if let Some(impl_trait_ref) = impl_trait_ref;
248-
if let ImplItemKind::Fn(FnSig { decl: impl_decl, .. }, impl_body_id) = &ii.kind;
249-
then {
250-
self.check_trait_method_impl_decl(ii, impl_decl, impl_trait_ref);
251-
let body = tcx.hir().body(*impl_body_id);
252-
self.visit_body(body);
253-
} else {
254-
walk_impl_item(self, ii)
255-
}
256-
}
257-
}
258240
}
259241

260242
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UseSelf {
261-
fn check_item(&mut self, cx: &LateContext<'a, 'tcx>, item: &'tcx Item<'_>) {
262-
if in_external_macro(cx.sess(), item.span) {
243+
fn check_impl_item(&mut self, cx: &LateContext<'a, 'tcx>, impl_item: &'tcx ImplItem<'_>) {
244+
if in_external_macro(cx.sess(), impl_item.span) {
263245
return;
264246
}
247+
248+
let parent_id = cx.tcx.hir().get_parent_item(impl_item.hir_id);
249+
let imp = cx.tcx.hir().expect_item(parent_id);
250+
265251
if_chain! {
266-
if let ItemKind::Impl{ self_ty: ref item_type, items: refs, .. } = item.kind;
267-
if let TyKind::Path(QPath::Resolved(_, ref item_path)) = item_type.kind;
252+
if let ItemKind::Impl { self_ty: hir_self_ty, .. } = imp.kind;
253+
if let TyKind::Path(QPath::Resolved(_, ref item_path)) = hir_self_ty.kind;
268254
then {
269255
let parameters = &item_path.segments.last().expect(SEGMENTS_MSG).args;
270256
let should_check = if let Some(ref params) = *parameters {
271-
!params.parenthesized && !params.args.iter().any(|arg| match arg {
272-
GenericArg::Lifetime(_) => true,
273-
_ => false,
274-
})
257+
!params.parenthesized
258+
&& !params.args.iter().any(|arg| match arg {
259+
GenericArg::Lifetime(_) => true,
260+
_ => false,
261+
})
275262
} else {
276263
true
277264
};
278265

279266
// TODO: don't short-circuit upon lifetime parameters
280267
if should_check {
281-
let self_ty= hir_ty_to_ty(cx.tcx, item_type);
282-
let visitor = &mut ImplVisitor {
283-
cx,
284-
item,
285-
self_ty,
286-
};
268+
let self_ty = hir_ty_to_ty(cx.tcx, hir_self_ty);
269+
let visitor = &mut ImplVisitor { cx, self_ty };
287270

288-
for impl_item_ref in refs {
289-
let impl_item = cx.tcx.hir().impl_item(impl_item_ref.id);
290-
visitor.visit_impl_item(impl_item);
271+
let tcx = cx.tcx;
272+
let impl_def_id = tcx.hir().local_def_id(imp.hir_id);
273+
let impl_trait_ref = tcx.impl_trait_ref(impl_def_id);
274+
if_chain! {
275+
if let Some(impl_trait_ref) = impl_trait_ref;
276+
if let ImplItemKind::Fn(FnSig { decl: impl_decl, .. }, impl_body_id) = &impl_item.kind;
277+
then {
278+
visitor.check_trait_method_impl_decl(impl_item, impl_decl, impl_trait_ref);
279+
let body = tcx.hir().body(*impl_body_id);
280+
visitor.visit_body(body);
281+
} else {
282+
walk_impl_item(visitor, impl_item)
283+
}
291284
}
292-
}
285+
}
293286
}
294287
}
295288
}

tests/ui/use_self.fixed

+44
Original file line numberDiff line numberDiff line change
@@ -378,3 +378,47 @@ mod issue3859 {
378378
}
379379
}
380380
} */
381+
382+
mod lint_at_item_level {
383+
struct Foo {}
384+
385+
#[allow(clippy::use_self)]
386+
impl Foo {
387+
fn new() -> Foo {
388+
Foo {}
389+
}
390+
fn test() -> Foo {
391+
Foo::new()
392+
}
393+
}
394+
395+
#[allow(clippy::use_self)]
396+
impl Default for Foo {
397+
fn default() -> Foo {
398+
Foo::new()
399+
}
400+
}
401+
}
402+
403+
mod lint_at_impl_item_level {
404+
struct Foo {}
405+
406+
impl Foo {
407+
#[allow(clippy::use_self)]
408+
fn new() -> Foo {
409+
Foo {}
410+
}
411+
412+
#[allow(clippy::use_self)]
413+
fn test() -> Foo {
414+
Foo::new()
415+
}
416+
}
417+
418+
impl Default for Foo {
419+
#[allow(clippy::use_self)]
420+
fn default() -> Foo {
421+
Foo::new()
422+
}
423+
}
424+
}

tests/ui/use_self.rs

+44
Original file line numberDiff line numberDiff line change
@@ -378,3 +378,47 @@ mod issue3859 {
378378
}
379379
}
380380
} */
381+
382+
mod lint_at_item_level {
383+
struct Foo {}
384+
385+
#[allow(clippy::use_self)]
386+
impl Foo {
387+
fn new() -> Foo {
388+
Foo {}
389+
}
390+
fn test() -> Foo {
391+
Foo::new()
392+
}
393+
}
394+
395+
#[allow(clippy::use_self)]
396+
impl Default for Foo {
397+
fn default() -> Foo {
398+
Foo::new()
399+
}
400+
}
401+
}
402+
403+
mod lint_at_impl_item_level {
404+
struct Foo {}
405+
406+
impl Foo {
407+
#[allow(clippy::use_self)]
408+
fn new() -> Foo {
409+
Foo {}
410+
}
411+
412+
#[allow(clippy::use_self)]
413+
fn test() -> Foo {
414+
Foo::new()
415+
}
416+
}
417+
418+
impl Default for Foo {
419+
#[allow(clippy::use_self)]
420+
fn default() -> Foo {
421+
Foo::new()
422+
}
423+
}
424+
}

tests/ui/use_self.stderr

+12-12
Original file line numberDiff line numberDiff line change
@@ -70,18 +70,6 @@ LL | use_self_expand!(); // Should lint in local macros
7070
|
7171
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
7272

73-
error: unnecessary structure name repetition
74-
--> $DIR/use_self.rs:151:21
75-
|
76-
LL | fn baz() -> Foo {
77-
| ^^^ help: use the applicable keyword: `Self`
78-
79-
error: unnecessary structure name repetition
80-
--> $DIR/use_self.rs:152:13
81-
|
82-
LL | Foo {}
83-
| ^^^ help: use the applicable keyword: `Self`
84-
8573
error: unnecessary structure name repetition
8674
--> $DIR/use_self.rs:139:29
8775
|
@@ -94,6 +82,18 @@ error: unnecessary structure name repetition
9482
LL | Bar { foo: Foo {} }
9583
| ^^^ help: use the applicable keyword: `Self`
9684

85+
error: unnecessary structure name repetition
86+
--> $DIR/use_self.rs:151:21
87+
|
88+
LL | fn baz() -> Foo {
89+
| ^^^ help: use the applicable keyword: `Self`
90+
91+
error: unnecessary structure name repetition
92+
--> $DIR/use_self.rs:152:13
93+
|
94+
LL | Foo {}
95+
| ^^^ help: use the applicable keyword: `Self`
96+
9797
error: unnecessary structure name repetition
9898
--> $DIR/use_self.rs:169:21
9999
|

0 commit comments

Comments
 (0)