Skip to content

Commit 10d7a6e

Browse files
committed
---
yaml --- r: 31473 b: refs/heads/dist-snap c: f7382c4 h: refs/heads/master i: 31471: fe72d02 v: v3
1 parent 4c4e5e6 commit 10d7a6e

File tree

4 files changed

+46
-2
lines changed

4 files changed

+46
-2
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,6 @@ refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b
88
refs/heads/try2: d0c6ce338884ee21843f4b40bf6bf18d222ce5df
99
refs/heads/incoming: d9317a174e434d4c99fc1a37fd7dc0d2f5328d37
10-
refs/heads/dist-snap: a0d05844ed7fa894608300646a1c086b43c21585
10+
refs/heads/dist-snap: f7382c454fb92f6c28ac6198821304c0ae2a080a
1111
refs/tags/release-0.2: c870d2dffb391e14efb05aa27898f1f6333a9596
1212
refs/tags/release-0.3: b5f0d0f648d9a6153664837026ba1be43d3e2503

branches/dist-snap/src/rustc/middle/resolve3.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ import str::{connect, split_str};
4747
import vec::pop;
4848

4949
import std::list::{cons, list, nil};
50-
import std::map::{hashmap, int_hash, str_hash};
50+
import std::map::{hashmap, int_hash};
5151
import ASTMap = syntax::ast_map::map;
5252
import str_eq = str::eq;
5353

branches/dist-snap/src/rustc/middle/typeck/check.rs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,29 @@ fn check_class_member(ccx: @crate_ctxt, class_t: ty::t,
376376
}
377377
}
378378

379+
fn check_no_duplicate_fields(tcx: ty::ctxt, fields:
380+
~[(ast::ident, span)]) {
381+
let field_names = hashmap::<@~str, span>(|x| str::hash(*x),
382+
|x,y| str::eq(*x, *y));
383+
for fields.each |p| {
384+
let (id, sp) = p;
385+
alt field_names.find(id) {
386+
some(orig_sp) {
387+
tcx.sess.span_err(sp, #fmt("Duplicate field \
388+
name %s in record type declaration",
389+
*id));
390+
tcx.sess.span_note(orig_sp, ~"First declaration of \
391+
this field occurred here");
392+
break;
393+
}
394+
none {
395+
field_names.insert(id, sp);
396+
}
397+
}
398+
}
399+
400+
}
401+
379402
fn check_item(ccx: @crate_ctxt, it: @ast::item) {
380403
alt it.node {
381404
ast::item_const(_, e) { check_const(ccx, it.span, e, it.id); }
@@ -429,6 +452,14 @@ fn check_item(ccx: @crate_ctxt, it: @ast::item) {
429452
ast::item_ty(t, tps) {
430453
let tpt_ty = ty::node_id_to_type(ccx.tcx, it.id);
431454
check_bounds_are_used(ccx, t.span, tps, tpt_ty);
455+
// If this is a record ty, check for duplicate fields
456+
alt t.node {
457+
ast::ty_rec(fields) {
458+
check_no_duplicate_fields(ccx.tcx, fields.map(|f|
459+
(f.node.ident, f.span)));
460+
}
461+
_ {}
462+
}
432463
}
433464
ast::item_foreign_mod(m) {
434465
if syntax::attr::foreign_abi(it.attrs) ==
@@ -1617,6 +1648,13 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
16171648
fn get_node(f: spanned<field>) -> field { f.node }
16181649
let typ = ty::mk_rec(tcx, vec::map(fields_t, get_node));
16191650
fcx.write_ty(id, typ);
1651+
/* Check for duplicate fields */
1652+
/* Only do this check if there's no base expr -- the reason is
1653+
that we're extending a record we know has no dup fields, and
1654+
it would be ill-typed anyway if we duplicated one of its
1655+
fields */
1656+
check_no_duplicate_fields(tcx, fields.map(|f|
1657+
(f.node.ident, f.span)));
16201658
}
16211659
some(bexpr) {
16221660
let bexpr_t = fcx.expr_ty(bexpr);
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
type cat = {cat_name: ~str, cat_name: int}; //~ ERROR Duplicate field name cat_name
2+
3+
fn main()
4+
{
5+
io::println(int::str({x: 1, x: 2}.x)); //~ ERROR Duplicate field name x
6+
}

0 commit comments

Comments
 (0)