Skip to content

Commit

Permalink
Fix checking of duplicate and missing struct field initializers. Closes
Browse files Browse the repository at this point in the history
#3486. Closes #3892
  • Loading branch information
brson committed Oct 31, 2012
1 parent b2462aa commit cb4de73
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 5 deletions.
14 changes: 9 additions & 5 deletions src/rustc/middle/typeck/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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| {
Expand All @@ -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)) => {
Expand All @@ -1486,18 +1488,20 @@ 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;
}
}
}

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(
Expand Down
10 changes: 10 additions & 0 deletions src/test/compile-fail/struct-fields-dupe.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
struct BuildData {
foo: int,
}

fn main() {
let foo = BuildData {
foo: 0,
foo: 0 //~ ERROR field `foo` specified more than once
};
}
10 changes: 10 additions & 0 deletions src/test/compile-fail/struct-fields-missing.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
struct BuildData {
foo: int,
bar: ~int
}

fn main() {
let foo = BuildData { //~ ERROR missing field: `bar`
foo: 0
};
}
10 changes: 10 additions & 0 deletions src/test/compile-fail/struct-fields-too-many.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
struct BuildData {
foo: int,
}

fn main() {
let foo = BuildData {
foo: 0,
bar: 0 //~ ERROR structure has no field named `bar`
};
}

0 comments on commit cb4de73

Please sign in to comment.