]> git.lizzy.rs Git - rust.git/commitdiff
Disallow duplicate bindings of struct fields
authorAlex Crichton <alex@alexcrichton.com>
Mon, 2 Dec 2013 22:20:27 +0000 (14:20 -0800)
committerAlex Crichton <alex@alexcrichton.com>
Mon, 2 Dec 2013 22:20:27 +0000 (14:20 -0800)
Closes #9725

src/librustc/middle/typeck/check/_match.rs
src/test/compile-fail/issue-9725.rs [new file with mode: 0644]

index 2e2d2232421930131ac696bd5992b2240f258f2a..4623c0bc6d86524ae94b78fc2195ca900c4a2bfa 100644 (file)
@@ -294,17 +294,24 @@ pub fn check_struct_pat_fields(pcx: &pat_ctxt,
                                etc: bool) {
     let tcx = pcx.fcx.ccx.tcx;
 
-    // Index the class fields.
+    // Index the class fields. The second argument in the tuple is whether the
+    // field has been bound yet or not.
     let mut field_map = HashMap::new();
     for (i, class_field) in class_fields.iter().enumerate() {
-        field_map.insert(class_field.name, i);
+        field_map.insert(class_field.name, (i, false));
     }
 
     // Typecheck each field.
     let mut found_fields = HashSet::new();
     for field in fields.iter() {
-        match field_map.find(&field.ident.name) {
-            Some(&index) => {
+        match field_map.find_mut(&field.ident.name) {
+            Some(&(_, true)) => {
+                tcx.sess.span_err(span,
+                    format!("field `{}` bound twice in pattern",
+                            tcx.sess.str_of(field.ident)));
+            }
+            Some(&(index, ref mut used)) => {
+                *used = true;
                 let class_field = class_fields[index];
                 let field_type = ty::lookup_field_type(tcx,
                                                        class_id,
diff --git a/src/test/compile-fail/issue-9725.rs b/src/test/compile-fail/issue-9725.rs
new file mode 100644 (file)
index 0000000..2a08963
--- /dev/null
@@ -0,0 +1,15 @@
+// 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.
+
+struct A { foo: int }
+
+fn main() {
+    let A { foo, foo } = A { foo: 3 }; //~ ERROR: field `foo` bound twice
+}