about summary refs log tree commit diff
path: root/clippy_lints/src/reference.rs
diff options
context:
space:
mode:
authorOliver Schneider <oli-obk@users.noreply.github.com>2018-05-28 13:50:31 +0200
committerGitHub <noreply@github.com>2018-05-28 13:50:31 +0200
commit0d1e06d638ccd369eb3fda74cc862de828877b4d (patch)
tree9b457108cc996bf7acf7f6fb0775cb59ea3866b9 /clippy_lints/src/reference.rs
parentb979f62aab92b6ec242880e0dfa9c13161343881 (diff)
parent8b679176fade98d8908f3950506f53b3a5b27910 (diff)
Merge pull request #2808 from Aaronepower/master
Added lint for unnecessary references.
Diffstat (limited to 'clippy_lints/src/reference.rs')
-rw-r--r--clippy_lints/src/reference.rs50
1 files changed, 50 insertions, 0 deletions
diff --git a/clippy_lints/src/reference.rs b/clippy_lints/src/reference.rs
index ffdb02216dc..4b173a58563 100644
--- a/clippy_lints/src/reference.rs
+++ b/clippy_lints/src/reference.rs
@@ -54,3 +54,53 @@ impl EarlyLintPass for Pass {
         }
     }
 }
+
+/// **What it does:** Checks for references in expressions that use
+/// auto dereference.
+///
+/// **Why is this bad?** The reference is a no-op and is automatically
+/// dereferenced by the compiler and makes the code less clear.
+///
+/// **Example:**
+/// ```rust
+/// struct Point(u32, u32);
+/// let point = Foo(30, 20);
+/// let x = (&point).x;
+/// ```
+declare_clippy_lint! {
+    pub REF_IN_DEREF,
+    complexity,
+    "Use of reference in auto dereference expression."
+}
+
+pub struct DerefPass;
+
+impl LintPass for DerefPass {
+    fn get_lints(&self) -> LintArray {
+        lint_array!(REF_IN_DEREF)
+    }
+}
+
+impl EarlyLintPass for DerefPass {
+    fn check_expr(&mut self, cx: &EarlyContext, e: &Expr) {
+        if_chain! {
+            if let ExprKind::Field(ref object, ref field_name) = e.node;
+            if let ExprKind::Paren(ref parened) = object.node;
+            if let ExprKind::AddrOf(_, ref inner) = parened.node;
+            then {
+                span_lint_and_sugg(
+                    cx,
+                    REF_IN_DEREF,
+                    object.span,
+                    "Creating a reference that is immediately dereferenced.",
+                    "try this",
+                    format!(
+                        "{}.{}",
+                        snippet(cx, inner.span, "_"),
+                        snippet(cx, field_name.span, "_")
+                    )
+                );
+            }
+        }
+    }
+}