about summary refs log tree commit diff
diff options
context:
space:
mode:
authorBrian Anderson <banderson@mozilla.com>2012-10-31 13:56:08 -0700
committerBrian Anderson <banderson@mozilla.com>2012-10-31 13:56:41 -0700
commitcb4de738cfe479418511025cdac7a33b8b36c407 (patch)
tree27358e5ef50a56947a227dec50eacd9ad0c29d12
parentb2462aa0e1d5a63a888b32656b3f0e14c818c9ac (diff)
downloadrust-cb4de738cfe479418511025cdac7a33b8b36c407.tar.gz
rust-cb4de738cfe479418511025cdac7a33b8b36c407.zip
Fix checking of duplicate and missing struct field initializers. Closes #3486. Closes #3892
-rw-r--r--src/rustc/middle/typeck/check.rs14
-rw-r--r--src/test/compile-fail/struct-fields-dupe.rs10
-rw-r--r--src/test/compile-fail/struct-fields-missing.rs10
-rw-r--r--src/test/compile-fail/struct-fields-too-many.rs10
4 files changed, 39 insertions, 5 deletions
diff --git a/src/rustc/middle/typeck/check.rs b/src/rustc/middle/typeck/check.rs
index 5fc92b2d0d0..044b95915cd 100644
--- a/src/rustc/middle/typeck/check.rs
+++ b/src/rustc/middle/typeck/check.rs
@@ -1457,6 +1457,8 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
         let tcx = fcx.ccx.tcx;
         let mut bot = false;
 
+        error!("%? %?", ast_fields.len(), field_types.len());
+
         let class_field_map = HashMap();
         let mut fields_found = 0;
         for field_types.each |field| {
@@ -1470,7 +1472,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
                 None => {
                     tcx.sess.span_err(
                         field.span,
-                        fmt!("structure has no field named field named `%s`",
+                        fmt!("structure has no field named `%s`",
                              tcx.sess.str_of(field.node.ident)));
                 }
                 Some((_, true)) => {
@@ -1486,6 +1488,8 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
                     bot |= check_expr(fcx,
                                       field.node.expr,
                                       Some(expected_field_type));
+                    class_field_map.insert(
+                        field.node.ident, (field_id, true));
                     fields_found += 1;
                 }
             }
@@ -1493,11 +1497,11 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
 
         if check_completeness {
             // Make sure the programmer specified all the fields.
-            assert fields_found <= ast_fields.len();
-            if fields_found < ast_fields.len() {
+            assert fields_found <= field_types.len();
+            if fields_found < field_types.len() {
                 let mut missing_fields = ~[];
-                for ast_fields.each |class_field| {
-                    let name = class_field.node.ident;
+                for field_types.each |class_field| {
+                    let name = class_field.ident;
                     let (_, seen) = class_field_map.get(name);
                     if !seen {
                         missing_fields.push(
diff --git a/src/test/compile-fail/struct-fields-dupe.rs b/src/test/compile-fail/struct-fields-dupe.rs
new file mode 100644
index 00000000000..43436e36cf7
--- /dev/null
+++ b/src/test/compile-fail/struct-fields-dupe.rs
@@ -0,0 +1,10 @@
+struct BuildData {
+    foo: int,
+}
+
+fn main() {
+    let foo = BuildData {
+        foo: 0,
+        foo: 0 //~ ERROR field `foo` specified more than once
+    };
+}
\ No newline at end of file
diff --git a/src/test/compile-fail/struct-fields-missing.rs b/src/test/compile-fail/struct-fields-missing.rs
new file mode 100644
index 00000000000..5e6098fbe95
--- /dev/null
+++ b/src/test/compile-fail/struct-fields-missing.rs
@@ -0,0 +1,10 @@
+struct BuildData {
+    foo: int,
+    bar: ~int
+}
+
+fn main() {
+    let foo = BuildData { //~ ERROR missing field: `bar`
+        foo: 0
+    };
+}
diff --git a/src/test/compile-fail/struct-fields-too-many.rs b/src/test/compile-fail/struct-fields-too-many.rs
new file mode 100644
index 00000000000..f3780aadc11
--- /dev/null
+++ b/src/test/compile-fail/struct-fields-too-many.rs
@@ -0,0 +1,10 @@
+struct BuildData {
+    foo: int,
+}
+
+fn main() {
+    let foo = BuildData {
+        foo: 0,
+        bar: 0 //~ ERROR structure has no field named `bar`
+    };
+}