about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2013-11-17 06:21:47 -0800
committerbors <bors@rust-lang.org>2013-11-17 06:21:47 -0800
commit5208332a1a0cc2d07d52c117a6abe7e2c8c1f36e (patch)
tree5924bc626624a4afdf17fe34c0e5f8a5a0e936c2
parent6c8e33753c0cc510730d5a82a6ce0d7567cf6722 (diff)
parent6bd8bb51a0c148c297b2396929149c5e946993c1 (diff)
auto merge of #10518 : huonw/rust/6911, r=alexcrichton
Bringing it into line with the unused-variable one,

    fn main() {
        let mut _a = 1;
    }

will not warn that `_a` is never used mutably.

Fixes #6911.
-rw-r--r--src/librustc/middle/lint.rs31
-rw-r--r--src/test/compile-fail/lint-unused-mut-variables.rs4
2 files changed, 21 insertions, 14 deletions
diff --git a/src/librustc/middle/lint.rs b/src/librustc/middle/lint.rs
index bc6cc00b786..9395ebefe87 100644
--- a/src/librustc/middle/lint.rs
+++ b/src/librustc/middle/lint.rs
@@ -883,20 +883,23 @@ fn check_unused_unsafe(cx: &Context, e: &ast::Expr) {
 
 fn check_unused_mut_pat(cx: &Context, p: @ast::Pat) {
     match p.node {
-        ast::PatIdent(ast::BindByValue(ast::MutMutable), _, _) => {
-            let mut used = false;
-            let mut bindings = 0;
-            do pat_util::pat_bindings(cx.tcx.def_map, p) |_, id, _, _| {
-                used = used || cx.tcx.used_mut_nodes.contains(&id);
-                bindings += 1;
-            }
-            if !used {
-                let msg = if bindings == 1 {
-                    "variable does not need to be mutable"
-                } else {
-                    "variables do not need to be mutable"
-                };
-                cx.span_lint(unused_mut, p.span, msg);
+        ast::PatIdent(ast::BindByValue(ast::MutMutable),
+                      ref path, _) if pat_util::pat_is_binding(cx.tcx.def_map, p)=> {
+            // `let mut _a = 1;` doesn't need a warning.
+            let initial_underscore = match path.segments {
+                [ast::PathSegment { identifier: id, _ }] => {
+                    cx.tcx.sess.str_of(id).starts_with("_")
+                }
+                _ => {
+                    cx.tcx.sess.span_bug(p.span,
+                                         "mutable binding that doesn't \
+                                         consist of exactly one segment");
+                }
+            };
+
+            if !initial_underscore && !cx.tcx.used_mut_nodes.contains(&p.id) {
+                cx.span_lint(unused_mut, p.span,
+                             "variable does not need to be mutable");
             }
         }
         _ => ()
diff --git a/src/test/compile-fail/lint-unused-mut-variables.rs b/src/test/compile-fail/lint-unused-mut-variables.rs
index 4b382a3116a..3abacdba183 100644
--- a/src/test/compile-fail/lint-unused-mut-variables.rs
+++ b/src/test/compile-fail/lint-unused-mut-variables.rs
@@ -49,6 +49,10 @@ fn main() {
 
     let x = |mut y: int| y = 32;
     fn nothing(mut foo: int) { foo = 37; }
+
+    // leading underscore should avoid the warning, just like the
+    // unused variable lint.
+    let mut _allowed = 1;
 }
 
 fn callback(f: &fn()) {}