diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs index 759d2ebb624226f0e7e09e10f3dd1e91270e7d6b..85de170ed99e941e700d87dca777b29e9352eebf 100644 --- a/src/librustc/middle/resolve.rs +++ b/src/librustc/middle/resolve.rs @@ -3812,9 +3812,10 @@ fn resolve_function(&mut self, } Some(declaration) => { for argument in declaration.inputs.iter() { + let mut bindings_list = HashMap::new(); this.resolve_pattern(&*argument.pat, ArgumentIrrefutableMode, - None); + &mut bindings_list); this.resolve_type(&*argument.ty); @@ -4045,7 +4046,10 @@ fn resolve_local(&mut self, local: &Local) { } // Resolve the pattern. - self.resolve_pattern(&*local.pat, LocalIrrefutableMode, None); + let mut bindings_list = HashMap::new(); + self.resolve_pattern(&*local.pat, + LocalIrrefutableMode, + &mut bindings_list); } // build a map from pattern identifiers to binding-info's. @@ -4114,9 +4118,7 @@ fn resolve_arm(&mut self, arm: &Arm) { let mut bindings_list = HashMap::new(); for pattern in arm.pats.iter() { - self.resolve_pattern(&**pattern, - RefutableMode, - Some(&mut bindings_list)); + self.resolve_pattern(&**pattern, RefutableMode, &mut bindings_list); } // This has to happen *after* we determine which @@ -4262,7 +4264,7 @@ fn resolve_pattern(&mut self, mode: PatternBindingMode, // Maps idents to the node ID for the (outermost) // pattern that binds them - mut bindings_list: Option<&mut HashMap>) { + bindings_list: &mut HashMap) { let pat_id = pattern.id; walk_pat(pattern, |pattern| { match pattern.node { @@ -4351,43 +4353,27 @@ struct or enum variant", // because that breaks the assumptions later // passes make about or-patterns.) - match bindings_list { - Some(ref mut bindings_list) - if !bindings_list.contains_key(&renamed) => { - let this = &mut *self; - let value_ribs = this.value_ribs.borrow(); - let length = value_ribs.len(); - let last_rib = value_ribs.get( - length - 1); - last_rib.bindings.borrow_mut() - .insert(renamed, DlDef(def)); - bindings_list.insert(renamed, pat_id); - } - Some(ref mut b) => { - if b.find(&renamed) == Some(&pat_id) { - // Then this is a duplicate variable - // in the same disjunct, which is an - // error - self.resolve_error(pattern.span, - format!("identifier `{}` is bound \ - more than once in the same \ - pattern", - path_to_str(path)).as_slice()); - } - // Not bound in the same pattern: do nothing - } - None => { - let this = &mut *self; - { - let value_ribs = this.value_ribs.borrow(); - let length = value_ribs.len(); - let last_rib = value_ribs.get( - length - 1); - last_rib.bindings.borrow_mut() - .insert(renamed, DlDef(def)); - } - } + if !bindings_list.contains_key(&renamed) { + let this = &mut *self; + let value_ribs = this.value_ribs.borrow(); + let length = value_ribs.len(); + let last_rib = value_ribs.get( + length - 1); + last_rib.bindings.borrow_mut() + .insert(renamed, DlDef(def)); + bindings_list.insert(renamed, pat_id); + } else if bindings_list.find(&renamed) == + Some(&pat_id) { + // Then this is a duplicate variable in the + // same disjunction, which is an error. + self.resolve_error(pattern.span, + format!("identifier `{}` is bound \ + more than once in the same \ + pattern", + path_to_str(path)).as_slice()); } + // Else, not bound in the same pattern: do + // nothing. } } diff --git a/src/test/compile-fail/shadowing-in-the-same-pattern.rs b/src/test/compile-fail/shadowing-in-the-same-pattern.rs new file mode 100644 index 0000000000000000000000000000000000000000..0b78023d318af0bf03976223d30c68dc5897aca6 --- /dev/null +++ b/src/test/compile-fail/shadowing-in-the-same-pattern.rs @@ -0,0 +1,18 @@ +// Copyright 2013 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. + +// Test for issue #14581. + +fn f((a, a): (int, int)) {} //~ ERROR identifier `a` is bound more than once + +fn main() { + let (a, a) = (1, 1); //~ ERROR identifier `a` is bound more than once +} +