@@ -634,7 +634,7 @@ fn lookup_in_block(&ident id, &ast::block_ b, namespace ns)
634
634
ret none[ def] ;
635
635
}
636
636
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 ] {
638
638
alt ( i. node ) {
639
639
case ( ast:: item_const ( _, _, _, ?defid, _) ) {
640
640
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)
928
928
// Collision detection
929
929
930
930
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.
932
933
for each ( @tup( ast:: def_num, @indexed_mod) m in e. mod_map . items ( ) ) {
933
934
for each ( @tup( ident, list[ mod_index_entry] ) name in
934
935
m. _1 . index . items ( ) ) {
935
936
check_mod_name ( * e, name. _0 , name. _1 ) ;
936
937
}
937
938
}
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, _)
940
944
with walk:: default_visitor ( ) ) ;
941
945
walk:: walk_crate ( v, c) ;
942
- fn visit_item(@env e, &@ast::item i) {
943
-
944
- }*/
945
946
}
946
947
947
948
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 {
983
984
}
984
985
985
986
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
+
986
1110
// Local Variables:
987
1111
// mode: rust
988
1112
// fill-column: 78;
0 commit comments