diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index a3a0398e5ce1d..96d6269bfe17f 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 0000000000000..051edfe5f451b --- /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 or the MIT license +// , 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); + } + _ => {} + }; +}