about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2012-05-21 09:37:22 -0700
committerNiko Matsakis <niko@alum.mit.edu>2012-05-21 09:37:22 -0700
commit8e73bb6ea06cf52b52cb403c84106873519f1220 (patch)
tree7064a07c8cacdb8100ae166ddd064e74aab115c1
parent1ad5f7d2c144117d9bb45eb657fb378d386788bf (diff)
downloadrust-8e73bb6ea06cf52b52cb403c84106873519f1220.tar.gz
rust-8e73bb6ea06cf52b52cb403c84106873519f1220.zip
detect and report shadows in nested bindings
-rw-r--r--src/rustc/middle/resolve.rs41
-rw-r--r--src/test/compile-fail/pat-shadow-in-nested-binding.rs5
2 files changed, 26 insertions, 20 deletions
diff --git a/src/rustc/middle/resolve.rs b/src/rustc/middle/resolve.rs
index 4a2d03ec0c8..09e5907ebf9 100644
--- a/src/rustc/middle/resolve.rs
+++ b/src/rustc/middle/resolve.rs
@@ -681,28 +681,29 @@ fn visit_arm_with_scope(a: ast::arm, sc: scopes, v: vt<scopes>) {
 
 // This is only for irrefutable patterns (e.g. ones that appear in a let)
 // So if x occurs, and x is already known to be a enum, that's always an error
-fn visit_local_with_scope(e: @env, loc: @local, sc:scopes, v:vt<scopes>) {
-    // Check whether the given local has the same name as a enum that's
-    // in scope
-    // We disallow this, in order to make alt patterns consisting of
-    // a single identifier unambiguous (does the pattern "foo" refer
-    // to enum foo, or is it binding a new name foo?)
-    alt loc.node.pat.node {
-      pat_ident(an_ident,_) {
-          alt lookup_in_scope(*e, sc, loc.span, path_to_ident(an_ident),
-                              ns_val, false) {
-              some(ast::def_variant(enum_id,variant_id)) {
-                  // Declaration shadows an enum that's in scope.
-                  // That's an error.
-                  e.sess.span_err(loc.span,
-                    #fmt("declaration of `%s` shadows an \
-                          enum that's in scope",
-                         path_to_ident(an_ident)));
-                  }
+fn visit_local_with_scope(e: @env, loc: @local, &&sc: scopes, v:vt<scopes>) {
+    // Check whether the given local has the same name as a enum that's in
+    // scope. We disallow this, in order to make alt patterns consisting of a
+    // single identifier unambiguous (does the pattern "foo" refer to enum
+    // foo, or is it binding a new name foo?)
+    pat_util::walk_pat(loc.node.pat) { |p|
+        alt p.node {
+          pat_ident(path, _) {
+            alt lookup_in_scope(*e, sc, loc.span, path_to_ident(path),
+                                ns_val, false) {
+              some(ast::def_variant(enum_id, variant_id)) {
+                // Declaration shadows an enum that's in scope.
+                // That's an error.
+                e.sess.span_err(loc.span,
+                                #fmt("declaration of `%s` shadows an \
+                                      enum that's in scope",
+                                     path_to_ident(path)));
+              }
               _ {}
+            }
           }
-      }
-      _ {}
+          _ {}
+        }
     }
     visit::visit_local(loc, sc, v);
 }
diff --git a/src/test/compile-fail/pat-shadow-in-nested-binding.rs b/src/test/compile-fail/pat-shadow-in-nested-binding.rs
new file mode 100644
index 00000000000..60fb9b831ab
--- /dev/null
+++ b/src/test/compile-fail/pat-shadow-in-nested-binding.rs
@@ -0,0 +1,5 @@
+enum foo = uint;
+
+fn main() {
+    let (foo, _) = (2, 3); //! ERROR declaration of `foo` shadows an enum that's in scope
+}