diff options
| author | Brian Anderson <banderson@mozilla.com> | 2012-10-31 13:56:08 -0700 |
|---|---|---|
| committer | Brian Anderson <banderson@mozilla.com> | 2012-10-31 13:56:41 -0700 |
| commit | cb4de738cfe479418511025cdac7a33b8b36c407 (patch) | |
| tree | 27358e5ef50a56947a227dec50eacd9ad0c29d12 | |
| parent | b2462aa0e1d5a63a888b32656b3f0e14c818c9ac (diff) | |
| download | rust-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.rs | 14 | ||||
| -rw-r--r-- | src/test/compile-fail/struct-fields-dupe.rs | 10 | ||||
| -rw-r--r-- | src/test/compile-fail/struct-fields-missing.rs | 10 | ||||
| -rw-r--r-- | src/test/compile-fail/struct-fields-too-many.rs | 10 |
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` + }; +} |
