Skip to content

Commit 757b0c1

Browse files
author
Ariel Ben-Yehuda
committed
prohibit the lhs of an @-pattern being a constant
as this breaks code that worked under some conditions, this is a [breaking-change] Fixes #27033 Fixes #27077
1 parent 4c371bb commit 757b0c1

File tree

2 files changed

+30
-9
lines changed

2 files changed

+30
-9
lines changed

src/librustc_resolve/lib.rs

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2666,23 +2666,22 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
26662666
let pat_id = pattern.id;
26672667
walk_pat(pattern, |pattern| {
26682668
match pattern.node {
2669-
PatIdent(binding_mode, ref path1, _) => {
2670-
2671-
// The meaning of pat_ident with no type parameters
2669+
PatIdent(binding_mode, ref path1, ref at_rhs) => {
2670+
// The meaning of PatIdent with no type parameters
26722671
// depends on whether an enum variant or unit-like struct
26732672
// with that name is in scope. The probing lookup has to
26742673
// be careful not to emit spurious errors. Only matching
26752674
// patterns (match) can match nullary variants or
2676-
// unit-like structs. For binding patterns (let), matching
2677-
// such a value is simply disallowed (since it's rarely
2678-
// what you want).
2675+
// unit-like structs. For binding patterns (let
2676+
// and the LHS of @-patterns), matching such a value is
2677+
// simply disallowed (since it's rarely what you want).
2678+
let const_ok = mode == RefutableMode && at_rhs.is_none();
26792679

26802680
let ident = path1.node;
26812681
let renamed = mtwt::resolve(ident);
26822682

26832683
match self.resolve_bare_identifier_pattern(ident.name, pattern.span) {
2684-
FoundStructOrEnumVariant(def, lp)
2685-
if mode == RefutableMode => {
2684+
FoundStructOrEnumVariant(def, lp) if const_ok => {
26862685
debug!("(resolving pattern) resolving `{}` to \
26872686
struct or enum variant",
26882687
renamed);
@@ -2705,7 +2704,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
27052704
renamed)
27062705
);
27072706
}
2708-
FoundConst(def, lp) if mode == RefutableMode => {
2707+
FoundConst(def, lp) if const_ok => {
27092708
debug!("(resolving pattern) resolving `{}` to \
27102709
constant",
27112710
renamed);

src/test/compile-fail/issue-27033.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
fn main() {
12+
match Some(1) {
13+
None @ _ => {} //~ ERROR declaration of `None` shadows an enum variant
14+
};
15+
const C: u8 = 1;
16+
match 1 {
17+
C @ 2 => { //~ ERROR only irrefutable patterns allowed here
18+
println!("{}", C);
19+
}
20+
_ => {}
21+
};
22+
}

0 commit comments

Comments
 (0)