about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc_resolve/lib.rs17
-rw-r--r--src/test/compile-fail/issue-27033.rs22
2 files changed, 30 insertions, 9 deletions
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index a3a0398e5ce..96d6269bfe1 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -2666,23 +2666,22 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
         let pat_id = pattern.id;
         walk_pat(pattern, |pattern| {
             match pattern.node {
-                PatIdent(binding_mode, ref path1, _) => {
-
-                    // The meaning of pat_ident with no type parameters
+                PatIdent(binding_mode, ref path1, ref at_rhs) => {
+                    // The meaning of PatIdent with no type parameters
                     // depends on whether an enum variant or unit-like struct
                     // with that name is in scope. The probing lookup has to
                     // be careful not to emit spurious errors. Only matching
                     // patterns (match) can match nullary variants or
-                    // unit-like structs. For binding patterns (let), matching
-                    // such a value is simply disallowed (since it's rarely
-                    // what you want).
+                    // unit-like structs. For binding patterns (let
+                    // and the LHS of @-patterns), matching such a value is
+                    // simply disallowed (since it's rarely what you want).
+                    let const_ok = mode == RefutableMode && at_rhs.is_none();
 
                     let ident = path1.node;
                     let renamed = mtwt::resolve(ident);
 
                     match self.resolve_bare_identifier_pattern(ident.name, pattern.span) {
-                        FoundStructOrEnumVariant(def, lp)
-                                if mode == RefutableMode => {
+                        FoundStructOrEnumVariant(def, lp) if const_ok => {
                             debug!("(resolving pattern) resolving `{}` to \
                                     struct or enum variant",
                                    renamed);
@@ -2705,7 +2704,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                                     renamed)
                             );
                         }
-                        FoundConst(def, lp) if mode == RefutableMode => {
+                        FoundConst(def, lp) if const_ok => {
                             debug!("(resolving pattern) resolving `{}` to \
                                     constant",
                                    renamed);
diff --git a/src/test/compile-fail/issue-27033.rs b/src/test/compile-fail/issue-27033.rs
new file mode 100644
index 00000000000..051edfe5f45
--- /dev/null
+++ b/src/test/compile-fail/issue-27033.rs
@@ -0,0 +1,22 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+fn main() {
+    match Some(1) {
+        None @ _ => {} //~ ERROR declaration of `None` shadows an enum variant
+    };
+    const C: u8 = 1;
+    match 1 {
+        C @ 2 => { //~ ERROR only irrefutable patterns allowed here
+            println!("{}", C);
+        }
+        _ => {}
+    };
+}