Skip to content

Commit 87bf47a

Browse files
committed
auto merge of #14801 : pcwalton/rust/name-shadowing-in-one-pattern, r=alexcrichton
bindings and function arguments. Issue #14581. To fix code that this breaks, give the pattern identifiers different names. [breaking-change] r? @brson
2 parents 614e448 + c23748c commit 87bf47a

File tree

2 files changed

+46
-42
lines changed

2 files changed

+46
-42
lines changed

src/librustc/middle/resolve.rs

+28-42
Original file line numberDiff line numberDiff line change
@@ -3812,9 +3812,10 @@ impl<'a> Resolver<'a> {
38123812
}
38133813
Some(declaration) => {
38143814
for argument in declaration.inputs.iter() {
3815+
let mut bindings_list = HashMap::new();
38153816
this.resolve_pattern(&*argument.pat,
38163817
ArgumentIrrefutableMode,
3817-
None);
3818+
&mut bindings_list);
38183819

38193820
this.resolve_type(&*argument.ty);
38203821

@@ -4045,7 +4046,10 @@ impl<'a> Resolver<'a> {
40454046
}
40464047

40474048
// Resolve the pattern.
4048-
self.resolve_pattern(&*local.pat, LocalIrrefutableMode, None);
4049+
let mut bindings_list = HashMap::new();
4050+
self.resolve_pattern(&*local.pat,
4051+
LocalIrrefutableMode,
4052+
&mut bindings_list);
40494053
}
40504054

40514055
// build a map from pattern identifiers to binding-info's.
@@ -4114,9 +4118,7 @@ impl<'a> Resolver<'a> {
41144118

41154119
let mut bindings_list = HashMap::new();
41164120
for pattern in arm.pats.iter() {
4117-
self.resolve_pattern(&**pattern,
4118-
RefutableMode,
4119-
Some(&mut bindings_list));
4121+
self.resolve_pattern(&**pattern, RefutableMode, &mut bindings_list);
41204122
}
41214123

41224124
// This has to happen *after* we determine which
@@ -4262,7 +4264,7 @@ impl<'a> Resolver<'a> {
42624264
mode: PatternBindingMode,
42634265
// Maps idents to the node ID for the (outermost)
42644266
// pattern that binds them
4265-
mut bindings_list: Option<&mut HashMap<Name,NodeId>>) {
4267+
bindings_list: &mut HashMap<Name,NodeId>) {
42664268
let pat_id = pattern.id;
42674269
walk_pat(pattern, |pattern| {
42684270
match pattern.node {
@@ -4351,43 +4353,27 @@ impl<'a> Resolver<'a> {
43514353
// because that breaks the assumptions later
43524354
// passes make about or-patterns.)
43534355

4354-
match bindings_list {
4355-
Some(ref mut bindings_list)
4356-
if !bindings_list.contains_key(&renamed) => {
4357-
let this = &mut *self;
4358-
let value_ribs = this.value_ribs.borrow();
4359-
let length = value_ribs.len();
4360-
let last_rib = value_ribs.get(
4361-
length - 1);
4362-
last_rib.bindings.borrow_mut()
4363-
.insert(renamed, DlDef(def));
4364-
bindings_list.insert(renamed, pat_id);
4365-
}
4366-
Some(ref mut b) => {
4367-
if b.find(&renamed) == Some(&pat_id) {
4368-
// Then this is a duplicate variable
4369-
// in the same disjunct, which is an
4370-
// error
4371-
self.resolve_error(pattern.span,
4372-
format!("identifier `{}` is bound \
4373-
more than once in the same \
4374-
pattern",
4375-
path_to_str(path)).as_slice());
4376-
}
4377-
// Not bound in the same pattern: do nothing
4378-
}
4379-
None => {
4380-
let this = &mut *self;
4381-
{
4382-
let value_ribs = this.value_ribs.borrow();
4383-
let length = value_ribs.len();
4384-
let last_rib = value_ribs.get(
4385-
length - 1);
4386-
last_rib.bindings.borrow_mut()
4387-
.insert(renamed, DlDef(def));
4388-
}
4389-
}
4356+
if !bindings_list.contains_key(&renamed) {
4357+
let this = &mut *self;
4358+
let value_ribs = this.value_ribs.borrow();
4359+
let length = value_ribs.len();
4360+
let last_rib = value_ribs.get(
4361+
length - 1);
4362+
last_rib.bindings.borrow_mut()
4363+
.insert(renamed, DlDef(def));
4364+
bindings_list.insert(renamed, pat_id);
4365+
} else if bindings_list.find(&renamed) ==
4366+
Some(&pat_id) {
4367+
// Then this is a duplicate variable in the
4368+
// same disjunction, which is an error.
4369+
self.resolve_error(pattern.span,
4370+
format!("identifier `{}` is bound \
4371+
more than once in the same \
4372+
pattern",
4373+
path_to_str(path)).as_slice());
43904374
}
4375+
// Else, not bound in the same pattern: do
4376+
// nothing.
43914377
}
43924378
}
43934379

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// Copyright 2013 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+
// Test for issue #14581.
12+
13+
fn f((a, a): (int, int)) {} //~ ERROR identifier `a` is bound more than once
14+
15+
fn main() {
16+
let (a, a) = (1, 1); //~ ERROR identifier `a` is bound more than once
17+
}
18+

0 commit comments

Comments
 (0)