]> git.lizzy.rs Git - rust.git/blob - clippy_lints/src/needless_borrowed_ref.rs
Improve needless_borrowed_ref lint comments.
[rust.git] / clippy_lints / src / needless_borrowed_ref.rs
1 //! Checks for useless borrowed references.
2 //!
3 //! This lint is **warn** by default
4
5 use rustc::lint::*;
6 use rustc::hir::{MutImmutable, Pat, PatKind, BindingAnnotation};
7 use rustc::ty;
8 use utils::{span_lint, in_macro};
9
10 /// **What it does:** Checks for useless borrowed references.
11 ///
12 /// **Why is this bad?** It is completely useless and make the code look more
13 /// complex than it
14 /// actually is.
15 ///
16 /// **Known problems:** None.
17 ///
18 /// **Example:**
19 /// ```rust
20 ///     let mut v = Vec::<String>::new();
21 ///     let _ = v.iter_mut().filter(|&ref a| a.is_empty());
22 /// ```
23 /// This clojure takes a reference on something that has been matched as a
24 /// reference and
25 /// de-referenced.
26 /// As such, it could just be |a| a.is_empty()
27 declare_lint! {
28     pub NEEDLESS_BORROWED_REFERENCE,
29     Warn,
30     "taking a needless borrowed reference"
31 }
32
33 #[derive(Copy, Clone)]
34 pub struct NeedlessBorrowedRef;
35
36 impl LintPass for NeedlessBorrowedRef {
37     fn get_lints(&self) -> LintArray {
38         lint_array!(NEEDLESS_BORROWED_REFERENCE)
39     }
40 }
41
42 impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessBorrowedRef {
43     fn check_pat(&mut self, cx: &LateContext<'a, 'tcx>, pat: &'tcx Pat) {
44         if in_macro(pat.span) {
45             // OK, simple enough, lints doesn't check in macro.
46             return;
47         }
48
49         if_let_chain! {[
50             // Pat is a pattern whose node
51             // is a binding which "involves" an immutable reference...
52             let PatKind::Binding(BindingAnnotation::Ref, ..) = pat.node,
53             // Pattern's type is a reference. Get the type and mutability of referenced value (tam: TypeAndMut).
54             let ty::TyRef(_, ref tam) = cx.tables.pat_ty(pat).sty,
55             // Only lint immutable refs, because `&mut ref T` may be useful.
56             tam.mutbl == MutImmutable,
57         ], {
58             span_lint(cx, NEEDLESS_BORROWED_REFERENCE, pat.span, "this pattern takes a reference on something that is being de-referenced")
59         }}
60     }
61 }