Skip to content

Commit cb104ea

Browse files
committed
---
yaml --- r: 2652 b: refs/heads/master c: 8a7b544 h: refs/heads/master v: v3
1 parent 6b501d7 commit cb104ea

File tree

4 files changed

+140
-9
lines changed

4 files changed

+140
-9
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
---
2-
refs/heads/master: 31d65453d47f243635ea17563db6b2c1127e9836
2+
refs/heads/master: 8a7b5449959b44fcc98d9fd0d5f81d86b44fd399

trunk/src/comp/front/parser.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -470,7 +470,6 @@ fn parse_ty(&parser p) -> @ast::ty {
470470
// FIXME: do something with this
471471
let ast::layer lyr = parse_layer(p);
472472

473-
let ast::ty t;
474473
if (eat_word(p, "bool")) { t = ast::ty_bool; }
475474
else if (eat_word(p, "int")) { t = ast::ty_int; }
476475
else if (eat_word(p, "uint")) { t = ast::ty_uint; }

trunk/src/comp/middle/resolve.rs

Lines changed: 131 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -634,7 +634,7 @@ fn lookup_in_block(&ident id, &ast::block_ b, namespace ns)
634634
ret none[def];
635635
}
636636

637-
fn found_def_item(@ast::item i, namespace ns) -> option::t[def] {
637+
fn found_def_item(&@ast::item i, namespace ns) -> option::t[def] {
638638
alt (i.node) {
639639
case (ast::item_const(_, _, _, ?defid, _)) {
640640
if (ns == ns_value) { ret some(ast::def_const(defid)); }
@@ -928,20 +928,21 @@ fn lookup_external(&env e, int cnum, vec[ident] ids, namespace ns)
928928
// Collision detection
929929

930930
fn check_for_collisions(&@env e, &ast::crate c) {
931-
auto msp = mie_span;
931+
// Module indices make checking those relatively simple -- just check each
932+
// name for multiple entities in the same namespace.
932933
for each (@tup(ast::def_num, @indexed_mod) m in e.mod_map.items()) {
933934
for each (@tup(ident, list[mod_index_entry]) name in
934935
m._1.index.items()) {
935936
check_mod_name(*e, name._0, name._1);
936937
}
937938
}
938-
/*
939-
auto v = rec(visit_item_pre = bind visit_item(e, _),
939+
940+
// Other scopes have to be checked the hard way.
941+
auto v = rec(visit_item_pre = bind check_item(e, _),
942+
visit_block_pre = bind check_block(e, _),
943+
visit_arm_pre = bind check_arm(e, _)
940944
with walk::default_visitor());
941945
walk::walk_crate(v, c);
942-
fn visit_item(@env e, &@ast::item i) {
943-
944-
}*/
945946
}
946947

947948
fn check_mod_name(&env e, &ident name, &list[mod_index_entry] entries) {
@@ -983,6 +984,129 @@ fn mie_span(&mod_index_entry mie) -> span {
983984
}
984985

985986

987+
fn check_item(@env e, &@ast::item i) {
988+
alt (i.node) {
989+
case (ast::item_fn(_, ?f, ?ty_params, _, _)) {
990+
check_fn(*e, i.span, f);
991+
ensure_unique(*e, i.span, ty_params, ident_id, "type parameter");
992+
}
993+
case (ast::item_obj(_, ?ob, ?ty_params, _, _)) {
994+
fn field_name(&ast::obj_field field) -> ident {
995+
ret field.ident;
996+
}
997+
ensure_unique(*e, i.span, ob.fields, field_name, "object field");
998+
for (@ast::method m in ob.methods) {
999+
check_fn(*e, m.span, m.node.meth);
1000+
}
1001+
ensure_unique(*e, i.span, ty_params, ident_id, "type parameter");
1002+
}
1003+
case (ast::item_tag(_, _, ?ty_params, _, _)) {
1004+
ensure_unique(*e, i.span, ty_params, ident_id, "type parameter");
1005+
}
1006+
case (_) {}
1007+
}
1008+
}
1009+
1010+
fn check_arm(@env e, &ast::arm a) {
1011+
fn walk_pat(checker ch, &@ast::pat p) {
1012+
alt (p.node) {
1013+
case (ast::pat_bind(?name, _, _)) {
1014+
add_name(ch, p.span, name);
1015+
}
1016+
case (ast::pat_tag(_, ?children, _)) {
1017+
for (@ast::pat child in children) {
1018+
walk_pat(ch, child);
1019+
}
1020+
}
1021+
case (_) {}
1022+
}
1023+
}
1024+
walk_pat(checker(*e, "binding"), a.pat);
1025+
}
1026+
1027+
fn check_block(@env e, &ast::block b) {
1028+
auto values = checker(*e, "value");
1029+
auto types = checker(*e, "type");
1030+
auto mods = checker(*e, "module");
1031+
1032+
for (@ast::stmt st in b.node.stmts) {
1033+
alt (st.node) {
1034+
case (ast::stmt_decl(?d,_)) {
1035+
alt (d.node) {
1036+
case (ast::decl_local(?loc)) {
1037+
add_name(values, d.span, loc.ident);
1038+
}
1039+
case (ast::decl_item(?it)) {
1040+
alt (it.node) {
1041+
case (ast::item_tag(?name, ?variants, _, _, _)) {
1042+
add_name(types, it.span, name);
1043+
for (ast::variant v in variants) {
1044+
add_name(values, v.span, v.node.name);
1045+
}
1046+
}
1047+
case (ast::item_const(?name, _, _, _, _)) {
1048+
add_name(values, it.span, name);
1049+
}
1050+
case (ast::item_fn(?name, _, _, _, _)) {
1051+
add_name(values, it.span, name);
1052+
}
1053+
case (ast::item_mod(?name, _, _)) {
1054+
add_name(mods, it.span, name);
1055+
}
1056+
case (ast::item_native_mod(?name, _, _)) {
1057+
add_name(mods, it.span, name);
1058+
}
1059+
case (ast::item_ty(?name, _, _, _, _)) {
1060+
add_name(types, it.span, name);
1061+
}
1062+
case (ast::item_obj(?name, _, _, _, _)) {
1063+
add_name(types, it.span, name);
1064+
add_name(values, it.span, name);
1065+
}
1066+
case (_) { }
1067+
}
1068+
}
1069+
}
1070+
}
1071+
case (_) {}
1072+
}
1073+
}
1074+
}
1075+
1076+
fn check_fn(&env e, &span sp, &ast::_fn f) {
1077+
fn arg_name(&ast::arg a) -> ident {
1078+
ret a.ident;
1079+
}
1080+
ensure_unique(e, sp, f.decl.inputs, arg_name, "argument");
1081+
}
1082+
1083+
type checker = @rec(mutable vec[ident] seen,
1084+
str kind,
1085+
session sess);
1086+
fn checker(&env e, str kind) -> checker {
1087+
let vec[ident] seen = [];
1088+
ret @rec(mutable seen=seen, kind=kind, sess=e.sess);
1089+
}
1090+
1091+
fn add_name(&checker ch, &span sp, &ident id) {
1092+
for (ident s in ch.seen) {
1093+
if (str::eq(s, id)) {
1094+
ch.sess.span_err(sp, "duplicate " + ch.kind + " name: " + id);
1095+
}
1096+
}
1097+
vec::push(ch.seen, id);
1098+
}
1099+
1100+
fn ident_id(&ident i) -> ident { ret i; }
1101+
1102+
fn ensure_unique[T](&env e, &span sp, &vec[T] elts, fn (&T) -> ident id,
1103+
&str kind) {
1104+
auto ch = checker(e, kind);
1105+
for (T elt in elts) {
1106+
add_name(ch, sp, id(elt));
1107+
}
1108+
}
1109+
9861110
// Local Variables:
9871111
// mode: rust
9881112
// fill-column: 78;
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// xfail-stage0
2+
3+
// error-pattern: duplicate value name: x
4+
5+
fn main() {
6+
auto x = 10;
7+
let int x = 20;
8+
}

0 commit comments

Comments
 (0)