]> git.proxmox.com Git - rustc.git/blob - src/tools/clippy/clippy_lints/src/unused_self.rs
New upstream version 1.53.0+dfsg1
[rustc.git] / src / tools / clippy / clippy_lints / src / unused_self.rs
1 use clippy_utils::diagnostics::span_lint_and_help;
2 use clippy_utils::visitors::LocalUsedVisitor;
3 use if_chain::if_chain;
4 use rustc_hir::{Impl, ImplItem, ImplItemKind, ItemKind};
5 use rustc_lint::{LateContext, LateLintPass};
6 use rustc_session::{declare_lint_pass, declare_tool_lint};
7
8 declare_clippy_lint! {
9 /// **What it does:** Checks methods that contain a `self` argument but don't use it
10 ///
11 /// **Why is this bad?** It may be clearer to define the method as an associated function instead
12 /// of an instance method if it doesn't require `self`.
13 ///
14 /// **Known problems:** None.
15 ///
16 /// **Example:**
17 /// ```rust,ignore
18 /// struct A;
19 /// impl A {
20 /// fn method(&self) {}
21 /// }
22 /// ```
23 ///
24 /// Could be written:
25 ///
26 /// ```rust,ignore
27 /// struct A;
28 /// impl A {
29 /// fn method() {}
30 /// }
31 /// ```
32 pub UNUSED_SELF,
33 pedantic,
34 "methods that contain a `self` argument but don't use it"
35 }
36
37 declare_lint_pass!(UnusedSelf => [UNUSED_SELF]);
38
39 impl<'tcx> LateLintPass<'tcx> for UnusedSelf {
40 fn check_impl_item(&mut self, cx: &LateContext<'tcx>, impl_item: &ImplItem<'_>) {
41 if impl_item.span.from_expansion() {
42 return;
43 }
44 let parent = cx.tcx.hir().get_parent_item(impl_item.hir_id());
45 let parent_item = cx.tcx.hir().expect_item(parent);
46 let assoc_item = cx.tcx.associated_item(impl_item.def_id);
47 if_chain! {
48 if let ItemKind::Impl(Impl { of_trait: None, .. }) = parent_item.kind;
49 if assoc_item.fn_has_self_parameter;
50 if let ImplItemKind::Fn(.., body_id) = &impl_item.kind;
51 let body = cx.tcx.hir().body(*body_id);
52 if let [self_param, ..] = body.params;
53 let self_hir_id = self_param.pat.hir_id;
54 if !LocalUsedVisitor::new(cx, self_hir_id).check_body(body);
55 then {
56 span_lint_and_help(
57 cx,
58 UNUSED_SELF,
59 self_param.span,
60 "unused `self` argument",
61 None,
62 "consider refactoring to a associated function",
63 );
64 }
65 }
66 }
67 }