Skip to content

Commit bfaa85b

Browse files
committed
Detect duplicate field names in record literals and types
Closes #746
1 parent 2c12507 commit bfaa85b

File tree

1 file changed

+33
-16
lines changed

1 file changed

+33
-16
lines changed

src/comp/middle/resolve.rs

Lines changed: 33 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1209,7 +1209,9 @@ fn check_for_collisions(&@env e, &ast::crate c) {
12091209
auto v =
12101210
@rec(visit_item=bind check_item(e, _, _, _),
12111211
visit_block=bind check_block(e, _, _, _),
1212-
visit_arm=bind check_arm(e, _, _, _)
1212+
visit_arm=bind check_arm(e, _, _, _),
1213+
visit_expr=bind check_expr(e, _, _, _),
1214+
visit_ty=bind check_ty(e, _, _, _)
12131215
with *visit::default_visitor());
12141216
visit::visit_crate(c, (), visit::mk_vt(v));
12151217
}
@@ -1255,33 +1257,33 @@ fn mie_span(&mod_index_entry mie) -> span {
12551257
};
12561258
}
12571259

1258-
fn check_item(@env e, &@ast::item i, &() x, &vt[()] v) {
1260+
fn check_item(&@env e, &@ast::item i, &() x, &vt[()] v) {
12591261
visit::visit_item(i, x, v);
12601262
alt (i.node) {
12611263
case (ast::item_fn(?f, ?ty_params)) {
12621264
check_fn(*e, i.span, f);
1263-
ensure_unique_ivec(*e, i.span, ty_params, ident_id,
1265+
ensure_unique(*e, i.span, ty_params, ident_id,
12641266
"type parameter");
12651267
}
12661268
case (ast::item_obj(?ob, ?ty_params, _)) {
12671269
fn field_name(&ast::obj_field field) -> ident { ret field.ident; }
1268-
ensure_unique_ivec(*e, i.span, ob.fields, field_name,
1270+
ensure_unique(*e, i.span, ob.fields, field_name,
12691271
"object field");
12701272
for (@ast::method m in ob.methods) {
12711273
check_fn(*e, m.span, m.node.meth);
12721274
}
1273-
ensure_unique_ivec(*e, i.span, ty_params, ident_id,
1275+
ensure_unique(*e, i.span, ty_params, ident_id,
12741276
"type parameter");
12751277
}
12761278
case (ast::item_tag(_, ?ty_params)) {
1277-
ensure_unique_ivec(*e, i.span, ty_params, ident_id,
1279+
ensure_unique(*e, i.span, ty_params, ident_id,
12781280
"type parameter");
12791281
}
12801282
case (_) { }
12811283
}
12821284
}
12831285

1284-
fn check_arm(@env e, &ast::arm a, &() x, &vt[()] v) {
1286+
fn check_arm(&@env e, &ast::arm a, &() x, &vt[()] v) {
12851287
visit::visit_arm(a, x, v);
12861288
fn walk_pat(checker ch, &@ast::pat p) {
12871289
alt (p.node) {
@@ -1323,7 +1325,7 @@ fn check_arm(@env e, &ast::arm a, &() x, &vt[()] v) {
13231325
}
13241326
}
13251327

1326-
fn check_block(@env e, &ast::blk b, &() x, &vt[()] v) {
1328+
fn check_block(&@env e, &ast::blk b, &() x, &vt[()] v) {
13271329
visit::visit_block(b, x, v);
13281330
auto values = checker(*e, "value");
13291331
auto types = checker(*e, "type");
@@ -1371,7 +1373,29 @@ fn check_block(@env e, &ast::blk b, &() x, &vt[()] v) {
13711373

13721374
fn check_fn(&env e, &span sp, &ast::_fn f) {
13731375
fn arg_name(&ast::arg a) -> ident { ret a.ident; }
1374-
ensure_unique_ivec(e, sp, f.decl.inputs, arg_name, "argument");
1376+
ensure_unique(e, sp, f.decl.inputs, arg_name, "argument");
1377+
}
1378+
1379+
fn check_expr(&@env e, &@ast::expr ex, &() x, &vt[()] v) {
1380+
alt ex.node {
1381+
ast::expr_rec(?fields, _) {
1382+
fn field_name(&ast::field f) -> ident { ret f.node.ident; }
1383+
ensure_unique(*e, ex.span, fields, field_name, "field name");
1384+
}
1385+
_ {}
1386+
}
1387+
visit::visit_expr(ex, x, v);
1388+
}
1389+
1390+
fn check_ty(&@env e, &@ast::ty ty, &() x, &vt[()] v) {
1391+
alt ty.node {
1392+
ast::ty_rec(?fields) {
1393+
fn field_name(&ast::ty_field f) -> ident { ret f.node.ident; }
1394+
ensure_unique(*e, ty.span, fields, field_name, "field name");
1395+
}
1396+
_ {}
1397+
}
1398+
visit::visit_ty(ty, x, v);
13751399
}
13761400

13771401
type checker = @rec(mutable ident[] seen, str kind, session sess);
@@ -1398,13 +1422,6 @@ fn ensure_unique[T](&env e, &span sp, &T[] elts, fn(&T) -> ident id,
13981422
for (T elt in elts) { add_name(ch, sp, id(elt)); }
13991423
}
14001424

1401-
// FIXME: Remove me.
1402-
fn ensure_unique_ivec[T](&env e, &span sp, &T[] elts, fn(&T) -> ident id,
1403-
&str kind) {
1404-
auto ch = checker(e, kind);
1405-
for (T elt in elts) { add_name(ch, sp, id(elt)); }
1406-
}
1407-
14081425
// Local Variables:
14091426
// mode: rust
14101427
// fill-column: 78;

0 commit comments

Comments
 (0)