From aeb5a0e60cc7b61253fa486b4e3af4d537af7322 Mon Sep 17 00:00:00 2001
From: Devon Hollowood <devonhollowood@gmail.com>
Date: Sat, 12 Dec 2015 17:51:58 -0800
Subject: [PATCH] Reduce false positives

Add macro checking, and only lint for single leading underscores
---
 src/misc.rs | 17 +++++++++++------
 1 file changed, 11 insertions(+), 6 deletions(-)

diff --git a/src/misc.rs b/src/misc.rs
index 5c3aeeb7899..f46a26c10e1 100644
--- a/src/misc.rs
+++ b/src/misc.rs
@@ -334,19 +334,24 @@ impl LateLintPass for UsedUnderscoreBinding {
     fn check_expr(&mut self, cx: &LateContext, expr: &Expr) {
         let needs_lint = match expr.node {
             ExprPath(_, ref path) => {
-                path.segments.last().unwrap().identifier.name.as_str().chars().next() == Some('_') &&
-                (cx.tcx.def_map.borrow()).values().any(|res| match res.base_def {
+                let ident = path.segments.last()
+                                .expect("path should always have at least one segment")
+                                .identifier;
+                ident.name.as_str().chars().next() == Some('_') //starts with '_'
+                && ident.name.as_str().chars().skip(1).next() != Some('_') //doesn't start with "__"
+                && ident.name != ident.unhygienic_name //not in macro
+                && cx.tcx.def_map.borrow().values().any(|res| match res.base_def {
                                                   Def::DefLocal(_, _) => true,
                                                   _ => false
-                                            })
+                                            }) //local variable
             },
             ExprField(_, spanned) => spanned.node.as_str().chars().next() == Some('_'),
             _ => false
         };
         if needs_lint {
-            cx.span_lint(USED_UNDERSCORE_BINDING, expr.span, &format!(
-                "used binding which is prefixed with an underscore. A leading underscore signals\
-                 that a binding will not be used."));
+            cx.span_lint(USED_UNDERSCORE_BINDING, expr.span,
+                         "used binding which is prefixed with an underscore. A leading underscore\
+                          signals that a binding will not be used.");
         }
     }
 }