@@ -12,6 +12,7 @@ import util::common::new_str_hash;
12
12
import util:: common:: span;
13
13
import middle:: tstate:: ann:: ts_ann;
14
14
import std:: map:: hashmap;
15
+ import std:: list;
15
16
import std:: list:: list;
16
17
import std:: list:: nil;
17
18
import std:: list:: cons;
@@ -168,40 +169,43 @@ fn map_crate(&@env e, &ast::crate c) {
168
169
}
169
170
170
171
// Next, assemble the links for globbed imports.
171
-
172
- let @indexed_mod cur_mod = e. mod_map . get ( -1 ) ;
173
-
174
172
cell = @mutable nil[ scope] ;
175
- auto link_globs =
173
+ auto link_globs =
176
174
rec ( visit_crate_pre = bind push_env_for_crate ( cell, _) ,
177
175
visit_crate_post = bind pop_env_for_crate ( cell, _) ,
178
- visit_view_item_pre = bind link_glob ( e, cell, cur_mod , _) ,
179
- visit_item_pre = bind enter_i ( e , cell, cur_mod , _) ,
176
+ visit_view_item_pre = bind link_glob ( e, cell, _) ,
177
+ visit_item_pre = bind push_env_for_item ( cell, _) ,
180
178
visit_item_post = bind pop_env_for_item ( cell, _)
181
179
with walk:: default_visitor ( ) ) ;
182
180
walk:: walk_crate ( link_globs, c) ;
183
-
184
- fn enter_i ( @env e , @mutable list[ scope] sc , @indexed_mod cur_mod ,
185
- & @ast:: item i) {
186
- push_env_for_item ( sc, i) ;
187
- alt ( i. node ) {
188
- case ( ast:: item_mod ( _, _, ?defid) ) {
189
- cur_mod = e. mod_map . get ( defid. _1 ) ;
190
- }
191
- case ( ast:: item_native_mod ( _, _, ?defid) ) {
192
- cur_mod = e. mod_map . get ( defid. _1 ) ;
181
+
182
+ fn link_glob ( @env e , @mutable list[ scope] sc , & @ast:: view_item vi) {
183
+ fn find_mod ( @env e , list[ scope] sc ) -> @indexed_mod {
184
+ alt ( sc) {
185
+ case ( cons[ scope] ( scope_item ( ?i) , ?tl) ) {
186
+ alt ( i. node ) {
187
+ case ( ast:: item_mod ( _, _, ?defid) ) {
188
+ ret e. mod_map . get ( defid. _1 ) ;
189
+ }
190
+ case ( ast:: item_native_mod ( _, _, ?defid) ) {
191
+ ret e. mod_map . get ( defid. _1 ) ;
192
+ }
193
+ case ( _) {
194
+ be find_mod ( e, * tl) ;
195
+ }
196
+ }
197
+ }
198
+ case ( _) {
199
+ ret e. mod_map . get ( -1 ) ; //top-level
200
+ }
193
201
}
194
- case ( _) { }
195
202
}
196
- }
197
-
198
- fn link_glob ( @env e , @mutable list[ scope] sc , @indexed_mod cur_mod ,
199
- & @ast:: view_item vi) {
203
+
200
204
alt ( vi. node ) {
201
205
//if it really is a glob import, that is
202
206
case ( ast:: view_item_import_glob ( ?path, _) ) {
203
- cur_mod . glob_imports +=
204
- [ follow_import ( * e, * sc, path, vi. span ) ] ;
207
+ find_mod ( e , * sc ) . glob_imports
208
+ += [ follow_import ( * e, * sc, path, vi. span ) ] ;
205
209
}
206
210
case ( _) { }
207
211
}
@@ -518,10 +522,13 @@ fn lookup_in_scope(&env e, list[scope] sc, &span sp, &ident id, namespace ns)
518
522
-> option:: t [ def ] {
519
523
fn in_scope ( & env e, & span sp, & ident id, & scope s, namespace ns)
520
524
-> option:: t [ def ] {
525
+ //not recursing through globs
526
+ let list[ def] no_m = nil[ def] ;
527
+
521
528
alt ( s) {
522
529
case ( scope_crate ( ?c) ) {
523
530
auto defid = tup ( ast:: local_crate, -1 ) ;
524
- ret lookup_in_local_mod ( e, defid, sp, id, ns, inside) ;
531
+ ret lookup_in_local_mod ( e, defid, no_m , sp, id, ns, inside) ;
525
532
}
526
533
case ( scope_item ( ?it) ) {
527
534
alt ( it. node ) {
@@ -537,10 +544,12 @@ fn lookup_in_scope(&env e, list[scope] sc, &span sp, &ident id, namespace ns)
537
544
}
538
545
}
539
546
case ( ast:: item_mod ( _, _, ?defid) ) {
540
- ret lookup_in_local_mod ( e, defid, sp, id, ns, inside) ;
547
+ ret lookup_in_local_mod ( e, defid, no_m, sp,
548
+ id, ns, inside) ;
541
549
}
542
550
case ( ast:: item_native_mod ( _, ?m, ?defid) ) {
543
- ret lookup_in_local_native_mod ( e, defid, sp, id, ns) ;
551
+ ret lookup_in_local_native_mod ( e, defid, no_m,
552
+ sp, id, ns) ;
544
553
}
545
554
case ( ast:: item_ty ( _, _, ?ty_params, _, _) ) {
546
555
if ( ns == ns_type) {
@@ -768,26 +777,44 @@ fn lookup_in_mod_strict(&env e, def m, &span sp, &ident id,
768
777
769
778
fn lookup_in_mod ( & env e, def m, & span sp, & ident id, namespace ns, dir dr)
770
779
-> option:: t [ def ] {
771
- auto defid = ast:: def_id_of_def ( m) ;
772
- if ( defid. _0 != ast:: local_crate) { // examining a mod. in an ext. crate
773
- auto cached = e. ext_cache . find ( tup ( defid, id, ns) ) ;
774
- if ( !option:: is_none ( cached) ) { ret cached; }
775
- auto path = [ id] ;
776
- if ( defid. _1 != -1 ) {
777
- path = e. ext_map . get ( defid) + path;
778
- }
779
- auto fnd = lookup_external ( e, defid. _0 , path, ns) ;
780
- if ( !option:: is_none ( fnd) ) {
781
- e. ext_cache . insert ( tup ( defid, id, ns) , option:: get ( fnd) ) ;
782
- }
783
- ret fnd;
784
- }
780
+ be lookup_in_mod_recursively ( e, cons[ def] ( m, @nil[ def] ) , sp, id, ns, dr) ;
781
+ }
782
+
783
+ // this list is simply the stack of glob imports we have passed through
784
+ // (preventing cyclic glob imports from diverging)
785
+ fn lookup_in_mod_recursively ( & env e, list[ def] m , & span sp, & ident id,
786
+ namespace ns, dir dr) -> option:: t [ def ] {
785
787
alt ( m) {
786
- case ( ast:: def_mod ( ?defid) ) {
787
- ret lookup_in_local_mod ( e, defid, sp, id, ns, dr) ;
788
+ case ( cons[ def] ( ?mod_def, ?tl) ) {
789
+ if ( list:: has ( * tl, mod_def) ) {
790
+ ret none[ def] ; // import glob cycle detected; we're done
791
+ }
792
+ auto defid = ast:: def_id_of_def ( mod_def) ;
793
+ if ( defid. _0 != ast:: local_crate) {
794
+ // examining a module in an external crate
795
+ auto cached = e. ext_cache . find ( tup ( defid, id, ns) ) ;
796
+ if ( !option:: is_none ( cached) ) { ret cached; }
797
+ auto path = [ id] ;
798
+ if ( defid. _1 != -1 ) {
799
+ path = e. ext_map . get ( defid) + path;
800
+ }
801
+ auto fnd = lookup_external ( e, defid. _0 , path, ns) ;
802
+ if ( !option:: is_none ( fnd) ) {
803
+ e. ext_cache . insert ( tup ( defid, id, ns) , option:: get ( fnd) ) ;
804
+ }
805
+ ret fnd;
806
+ }
807
+ alt ( mod_def) {
808
+ case ( ast:: def_mod ( ?defid) ) {
809
+ ret lookup_in_local_mod ( e, defid, m, sp, id, ns, dr) ;
810
+ }
811
+ case ( ast:: def_native_mod ( ?defid) ) {
812
+ ret lookup_in_local_native_mod ( e, defid, m, sp, id, ns) ;
813
+ }
814
+ }
788
815
}
789
- case ( ast :: def_native_mod ( ?defid ) ) {
790
- ret lookup_in_local_native_mod ( e , defid , sp , id , ns ) ;
816
+ case ( _ ) {
817
+ e . sess . bug ( "lookup_in_mod_recursively needs a module" ) ; fail ;
791
818
}
792
819
}
793
820
}
@@ -825,8 +852,14 @@ fn lookup_import(&env e, def_id defid, namespace ns) -> option::t[def] {
825
852
fail;
826
853
}
827
854
828
- fn lookup_in_local_mod ( & env e, def_id defid, & span sp, & ident id,
829
- namespace ns, dir dr) -> option:: t [ def ] {
855
+
856
+ fn lookup_in_local_native_mod ( & env e, def_id defid, list[ def] m , & span sp,
857
+ & ident id, namespace ns) -> option:: t [ def ] {
858
+ ret lookup_in_local_mod ( e, defid, m, sp, id, ns, inside) ;
859
+ }
860
+
861
+ fn lookup_in_local_mod ( & env e, def_id defid, list[ def] m , & span sp,
862
+ & ident id, namespace ns, dir dr) -> option:: t [ def ] {
830
863
auto info = e. mod_map . get ( defid. _1 ) ;
831
864
if ( dr == outside && !ast:: is_exported ( id, option:: get ( info. m ) ) ) {
832
865
// if we're in a native mod, then dr==inside, so info.m is some _mod
@@ -848,26 +881,24 @@ fn lookup_in_local_mod(&env e, def_id defid, &span sp, &ident id,
848
881
}
849
882
}
850
883
// not local or explicitly imported; try globs:
851
- ret lookup_glob_in_mod ( e, info, sp, id, ns, dr) ;
884
+ ret lookup_glob_in_mod ( e, info, m , sp, id, ns, dr) ;
852
885
}
853
886
854
- fn lookup_glob_in_mod ( & env e, @indexed_mod info , & span sp, & ident id,
855
- namespace ns, dir dr) -> option:: t [ def ] {
856
- fn l_i_m ( & env e, & def d, & span sp, & ident id, namespace ns, dir dr)
857
- -> option:: t [ def ] {
858
- ret lookup_in_mod ( e, d, sp, id, ns, dr) ;
887
+ fn lookup_glob_in_mod ( & env e, @indexed_mod info , list[ def] m , & span sp,
888
+ & ident id, namespace ns, dir dr) -> option:: t [ def ] {
889
+ fn l_i_m_r ( & env e, list[ def] prev_ms , & def m, & span sp, & ident id,
890
+ namespace ns, dir dr) -> option:: t [ def ] {
891
+ be lookup_in_mod_recursively ( e, cons[ def] ( m, @prev_ms) ,
892
+ sp, id, ns, dr) ;
859
893
}
860
- auto matches = vec:: filter_map
861
- ( bind l_i_m ( e, _, sp, id, ns, dr) , info. glob_imports ) ;
894
+ auto matches = vec:: filter_map[ def, def]
895
+ ( bind l_i_m_r ( e, m, _, sp, id, ns, dr) ,
896
+ info. glob_imports ) ;
862
897
if ( vec:: len ( matches) == 0 u) {
863
898
ret none[ def] ;
864
899
} else if ( vec:: len ( matches) == 1 u) {
865
900
ret some[ def] ( matches. ( 0 ) ) ;
866
901
} else {
867
- for ( def d in matches) {
868
- e. sess . span_note ( sp, "'" + id + "' is defined at " +
869
- util:: common:: istr ( ast:: def_id_of_def ( d) . _1 ) ) ;
870
- }
871
902
e. sess . span_err ( sp, "'" + id + "' is glob-imported from" +
872
903
" multiple different modules." ) ;
873
904
fail;
@@ -914,10 +945,6 @@ fn lookup_in_mie(&env e, &mod_index_entry mie, namespace ns)
914
945
ret none[ def] ;
915
946
}
916
947
917
- fn lookup_in_local_native_mod ( & env e, def_id defid, & span sp, & ident id,
918
- namespace ns) -> option:: t [ def ] {
919
- ret lookup_in_local_mod ( e, defid, sp, id, ns, inside) ;
920
- }
921
948
922
949
923
950
// Module indexing
@@ -945,9 +972,8 @@ fn index_mod(&ast::_mod md) -> mod_index {
945
972
case ( ast:: view_item_import ( ?def_ident, _, _) ) {
946
973
add_to_index ( index, def_ident, mie_view_item ( it) ) ;
947
974
}
948
- case ( ast:: view_item_import_glob ( ?path, _) ) {
949
- //globbed imports have to be resolved lazily.
950
- }
975
+ //globbed imports have to be resolved lazily.
976
+ case ( ast:: view_item_import_glob ( _, _) ) { }
951
977
case ( ast:: view_item_export ( _) ) { }
952
978
}
953
979
}
@@ -995,6 +1021,7 @@ fn index_nmod(&ast::native_mod md) -> mod_index {
995
1021
case ( ast:: view_item_import ( ?def_ident, _, _) ) {
996
1022
add_to_index ( index, def_ident, mie_view_item ( it) ) ;
997
1023
}
1024
+ case ( ast:: view_item_import_glob ( _, _) ) { }
998
1025
case ( ast:: view_item_export ( _) ) { }
999
1026
}
1000
1027
}
0 commit comments