diff options
| author | Patrick Walton <pcwalton@mimiga.net> | 2014-06-10 14:39:10 -0700 |
|---|---|---|
| committer | Patrick Walton <pcwalton@mimiga.net> | 2014-06-11 13:23:04 -0700 |
| commit | c23748c59ce0969bf9251f6d4bb1882ca0045a78 (patch) | |
| tree | 1f81fa102cadaa0e97784d8d3590603da356fd42 /src | |
| parent | f0f9095f1daa3814c9589f38b574e51d394d1bbc (diff) | |
| download | rust-c23748c59ce0969bf9251f6d4bb1882ca0045a78.tar.gz rust-c23748c59ce0969bf9251f6d4bb1882ca0045a78.zip | |
librustc: Forbid identifiers that shadow in the same pattern in let
bindings and function arguments. Issue #14581. To fix code that this breaks, give the pattern identifiers different names. [breaking-change]
Diffstat (limited to 'src')
| -rw-r--r-- | src/librustc/middle/resolve.rs | 70 | ||||
| -rw-r--r-- | src/test/compile-fail/shadowing-in-the-same-pattern.rs | 18 |
2 files changed, 46 insertions, 42 deletions
diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs index 759d2ebb624..85de170ed99 100644 --- a/src/librustc/middle/resolve.rs +++ b/src/librustc/middle/resolve.rs @@ -3812,9 +3812,10 @@ impl<'a> Resolver<'a> { } 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 @@ impl<'a> Resolver<'a> { } // 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 @@ impl<'a> Resolver<'a> { 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 @@ impl<'a> Resolver<'a> { mode: PatternBindingMode, // Maps idents to the node ID for the (outermost) // pattern that binds them - mut bindings_list: Option<&mut HashMap<Name,NodeId>>) { + bindings_list: &mut HashMap<Name,NodeId>) { let pat_id = pattern.id; walk_pat(pattern, |pattern| { match pattern.node { @@ -4351,43 +4353,27 @@ impl<'a> Resolver<'a> { // 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 00000000000..0b78023d318 --- /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 <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. + +// 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 +} + |
