@@ -37,7 +37,6 @@ tag scope {
37
37
scope_fn ( ast:: fn_decl, ast:: proto, [ ast:: ty_param] ) ;
38
38
scope_native_item ( @ast:: native_item) ;
39
39
scope_loop ( @ast:: local) ; // there's only 1 decl per loop.
40
-
41
40
scope_block ( ast:: blk, @mutable uint, @mutable uint) ;
42
41
scope_arm ( ast:: arm) ;
43
42
}
@@ -105,6 +104,7 @@ type env =
105
104
ast_map : ast_map:: map ,
106
105
imports : hashmap < ast:: node_id , import_state > ,
107
106
mod_map : hashmap < ast:: node_id , @indexed_mod > ,
107
+ block_map : hashmap < ast:: node_id , [ glob_imp_def ] > ,
108
108
ext_map : hashmap < def_id , [ ident ] > ,
109
109
ext_cache : ext_hash ,
110
110
used_imports : { mutable track: bool ,
@@ -124,11 +124,12 @@ fn resolve_crate(sess: session, amap: ast_map::map, crate: @ast::crate) ->
124
124
{ def_map : def_map , ext_map : ext_map } {
125
125
let e =
126
126
@{ cstore: sess. get_cstore ( ) ,
127
- def_map: new_int_hash :: < def > ( ) ,
127
+ def_map: new_int_hash ( ) ,
128
128
ast_map: amap,
129
- imports: new_int_hash :: < import_state > ( ) ,
130
- mod_map: new_int_hash :: < @indexed_mod > ( ) ,
131
- ext_map: new_def_hash :: < [ ident ] > ( ) ,
129
+ imports: new_int_hash ( ) ,
130
+ mod_map: new_int_hash ( ) ,
131
+ block_map: new_int_hash ( ) ,
132
+ ext_map: new_def_hash ( ) ,
132
133
ext_cache: new_ext_hash ( ) ,
133
134
used_imports : { mutable track: false , mutable data: [ ] } ,
134
135
mutable reported: [ ] ,
@@ -149,14 +150,14 @@ fn resolve_crate(sess: session, amap: ast_map::map, crate: @ast::crate) ->
149
150
// resolve through them.
150
151
fn map_crate ( e : @env , c : @ast:: crate ) {
151
152
// First, find all the modules, and index the names that they contain
152
-
153
153
let v_map_mod =
154
154
@{ visit_view_item : bind index_vi( e, _, _, _) ,
155
- visit_item: bind index_i ( e, _, _, _)
156
- with * visit:: default_visitor :: < scopes > ( ) } ;
155
+ visit_item: bind index_i ( e, _, _, _) ,
156
+ visit_block: visit_block_with_scope
157
+ with * visit:: default_visitor :: < scopes > ( ) } ;
157
158
visit:: visit_crate ( * c, cons ( scope_crate, @nil) , visit:: mk_vt ( v_map_mod) ) ;
158
- // Register the top-level mod
159
159
160
+ // Register the top-level mod
160
161
e. mod_map . insert ( -1 ,
161
162
@{ m: some ( c. node . module ) ,
162
163
index: index_mod ( c. node . module ) ,
@@ -200,38 +201,36 @@ fn map_crate(e: @env, c: @ast::crate) {
200
201
_ { }
201
202
}
202
203
}
203
- // Next, assemble the links for globbed imports.
204
204
205
+ // Next, assemble the links for globbed imports.
205
206
let v_link_glob =
206
207
@{ visit_view_item : bind link_glob( e, _, _, _) ,
208
+ visit_block: visit_block_with_scope,
207
209
visit_item: visit_item_with_scope
208
- with * visit:: default_visitor :: < scopes > ( ) } ;
210
+ with * visit:: default_visitor :: < scopes > ( ) } ;
209
211
visit:: visit_crate ( * c, cons ( scope_crate, @nil) ,
210
212
visit:: mk_vt ( v_link_glob) ) ;
211
213
fn link_glob ( e : @env , vi : @ast:: view_item , sc : scopes , _v : vt < scopes > ) {
212
- fn find_mod ( e : @env , sc : scopes ) -> @indexed_mod {
213
- alt sc {
214
- cons( scope_item ( i) , tl) {
215
- alt i. node {
216
- ast:: item_mod ( _) | ast:: item_native_mod ( _) {
217
- ret e. mod_map . get ( i. id ) ;
218
- }
219
- _ { be find_mod( e, * tl) ; }
220
- }
221
- }
222
- _ {
223
- ret e. mod_map . get ( -1 ) ; //top-level
224
-
225
- }
226
- }
227
- }
228
214
alt vi. node {
229
215
//if it really is a glob import, that is
230
216
ast:: view_item_import_glob ( path, _) {
231
217
let imp = follow_import ( * e, sc, path, vi. span ) ;
232
218
if option:: is_some ( imp) {
233
- find_mod ( e, sc) . glob_imports +=
234
- [ { def: option:: get ( imp) , item: vi} ] ;
219
+ let glob = { def: option:: get ( imp) , item: vi} ; ;
220
+ alt sc {
221
+ cons( scope_item ( i) , _) {
222
+ e. mod_map . get ( i. id ) . glob_imports += [ glob] ;
223
+ }
224
+ cons ( scope_block ( b, _, _) , _) {
225
+ let globs = alt e. block_map . find ( b. node . id ) {
226
+ some ( globs) { globs + [ glob] } none. { [ glob] }
227
+ } ;
228
+ e. block_map . insert ( b. node . id , globs) ;
229
+ }
230
+ nil. {
231
+ e . mod_map . get ( -1 ) . glob_imports += [ glob] ;
232
+ }
233
+ }
235
234
}
236
235
}
237
236
_ { }
@@ -370,6 +369,7 @@ fn visit_fn_with_scope(e: @env, f: ast::_fn, tp: [ast::ty_param], sp: span,
370
369
fn visit_block_with_scope ( b : ast:: blk , sc : scopes , v : vt < scopes > ) {
371
370
let pos = @mutable 0 u, loc = @mutable 0 u;
372
371
let block_sc = cons ( scope_block ( b, pos, loc) , @sc) ;
372
+ for vi in b. node . view_items { v. visit_view_item ( vi, block_sc, v) ; }
373
373
for stmt in b. node . stmts {
374
374
v. visit_stmt ( stmt, block_sc, v) ; ;
375
375
* pos += 1 u; ;
@@ -426,9 +426,8 @@ fn follow_import(e: env, sc: scopes, path: [ident], sp: span) ->
426
426
alt option:: get ( dcur) {
427
427
ast:: def_mod ( _) | ast:: def_native_mod ( _) { ret dcur; }
428
428
_ {
429
- e. sess . span_err ( sp,
430
- str:: connect ( path, "::" ) +
431
- " does not name a module." ) ;
429
+ e. sess . span_err ( sp, str:: connect ( path, "::" ) +
430
+ " does not name a module." ) ;
432
431
ret none;
433
432
}
434
433
}
@@ -678,7 +677,7 @@ fn lookup_in_scope(e: env, sc: scopes, sp: span, name: ident, ns: namespace)
678
677
}
679
678
}
680
679
scope_block ( b, pos, loc) {
681
- ret lookup_in_block ( name, b. node , * pos, * loc, ns) ;
680
+ ret lookup_in_block ( e , name, sp , b. node , * pos, * loc, ns) ;
682
681
}
683
682
scope_arm ( a) {
684
683
if ns == ns_value {
@@ -793,8 +792,8 @@ fn lookup_in_obj(name: ident, ob: ast::_obj, ty_params: [ast::ty_param],
793
792
}
794
793
}
795
794
796
- fn lookup_in_block ( name : ident , b : ast:: blk_ , pos : uint , loc_pos : uint ,
797
- ns : namespace ) -> option:: t < def > {
795
+ fn lookup_in_block ( e : env , name : ident , sp : span , b : ast:: blk_ , pos : uint ,
796
+ loc_pos : uint , ns : namespace ) -> option:: t < def > {
798
797
let i = vec:: len ( b. stmts ) ;
799
798
while i > 0 u {
800
799
i -= 1 u;
@@ -849,7 +848,30 @@ fn lookup_in_block(name: ident, b: ast::blk_, pos: uint, loc_pos: uint,
849
848
_ { }
850
849
}
851
850
}
852
- ret none:: < def > ;
851
+ for vi in b. view_items {
852
+ alt vi. node {
853
+ ast:: view_item_import ( ident, _, id) {
854
+ if name == ident { ret lookup_import ( e, local_def ( id) , ns) ; }
855
+ }
856
+ ast:: view_item_import_from ( mod_path, idents, id) {
857
+ for ident in idents {
858
+ if name == ident. node . name {
859
+ ret lookup_import ( e, local_def ( ident. node . id ) , ns) ;
860
+ }
861
+ }
862
+ }
863
+ ast:: view_item_import_glob ( _, _) {
864
+ alt e. block_map . find ( b. id ) {
865
+ some ( globs) {
866
+ let found = lookup_in_globs ( e, globs, sp, name, ns, inside) ;
867
+ if found != none { ret found; }
868
+ }
869
+ _ { }
870
+ }
871
+ }
872
+ }
873
+ }
874
+ ret none;
853
875
}
854
876
855
877
fn found_def_item ( i : @ast:: item , ns : namespace ) -> option:: t < def > {
@@ -991,57 +1013,51 @@ fn lookup_in_local_mod(e: env, node_id: node_id, sp: span, id: ident,
991
1013
}
992
1014
}
993
1015
}
994
-
995
1016
// not local or explicitly imported; try globs:
996
1017
ret lookup_glob_in_mod ( e, info, sp, id, ns, outside) ;
997
1018
}
998
1019
999
- fn lookup_glob_in_mod( e : env , info : @indexed_mod , sp : span , id : ident ,
1000
- wanted_ns : namespace , dr : dir ) -> option:: t < def > {
1001
- fn per_ns( e : env , info : @indexed_mod , sp : span , id : ident , ns : namespace ,
1002
- dr : dir ) -> option:: t < def > {
1003
-
1004
- fn lookup_in_mod_ ( e : env , def : glob_imp_def , sp : span , name : ident ,
1005
- ns : namespace , dr : dir ) -> option:: t < glob_imp_def > {
1006
- alt lookup_in_mod ( e, def. def , sp, name, ns, dr) {
1007
- option:: some ( d) { option:: some ( { def: d, item: def. item } ) }
1008
- option:: none. { option:: none }
1009
- }
1020
+ fn lookup_in_globs ( e : env , globs : [ glob_imp_def ] , sp : span , id : ident ,
1021
+ ns : namespace , dr : dir ) -> option:: t < def > {
1022
+ fn lookup_in_mod_ ( e : env , def : glob_imp_def , sp : span , name : ident ,
1023
+ ns : namespace , dr : dir ) -> option:: t < glob_imp_def > {
1024
+ alt lookup_in_mod ( e, def. def , sp, name, ns, dr) {
1025
+ option:: some ( d) { option:: some ( { def: d, item: def. item } ) }
1026
+ option:: none. { option:: none }
1010
1027
}
1011
-
1012
- let matches =
1013
- vec:: filter_map ( bind lookup_in_mod_ ( e, _, sp, id, ns, dr) ,
1014
- { info. glob_imports } ) ;
1015
- if vec:: len ( matches) == 0 u {
1016
- ret none;
1017
- } else if vec:: len ( matches) == 1 u {
1018
- ret some ( matches[ 0 ] . def ) ;
1019
- } else {
1020
- for match: glob_imp_def in matches {
1021
- let sp = match . item . span ;
1022
- e. sess . span_note ( sp, #fmt[ "'%s' is imported here" , id] ) ;
1023
- }
1024
- e. sess . span_fatal ( sp,
1025
- "'" + id + "' is glob-imported from" +
1026
- " multiple different modules." ) ;
1028
+ }
1029
+ let matches =
1030
+ vec:: filter_map ( bind lookup_in_mod_ ( e, _, sp, id, ns, dr) ,
1031
+ { globs } ) ;
1032
+ if vec:: len ( matches) == 0 u {
1033
+ ret none;
1034
+ } else if vec:: len ( matches) == 1 u {
1035
+ ret some ( matches[ 0 ] . def ) ;
1036
+ } else {
1037
+ for match: glob_imp_def in matches {
1038
+ let sp = match . item . span ;
1039
+ e. sess . span_note ( sp, #fmt[ "'%s' is imported here" , id] ) ;
1027
1040
}
1041
+ e. sess . span_fatal ( sp, "'" + id + "' is glob-imported from" +
1042
+ " multiple different modules." ) ;
1028
1043
}
1044
+ }
1045
+
1046
+ fn lookup_glob_in_mod ( e : env , info : @indexed_mod , sp : span , id : ident ,
1047
+ wanted_ns : namespace , dr : dir ) -> option:: t < def > {
1029
1048
// since we don't know what names we have in advance,
1030
1049
// absence takes the place of todo()
1031
-
1032
1050
if !info. glob_imported_names . contains_key ( id) {
1033
1051
info. glob_imported_names . insert ( id, resolving ( sp) ) ;
1034
- let val = per_ns ( e, info, sp, id, ns_value, dr) ;
1035
- let typ = per_ns ( e, info, sp, id, ns_type, dr) ;
1036
- let md = per_ns ( e, info, sp, id, ns_module, dr) ;
1052
+ let val = lookup_in_globs ( e, info. glob_imports , sp, id, ns_value, dr) ;
1053
+ let typ = lookup_in_globs ( e, info. glob_imports , sp, id, ns_type, dr) ;
1054
+ let md = lookup_in_globs ( e, info. glob_imports , sp, id, ns_module, dr) ;
1037
1055
info. glob_imported_names . insert ( id, resolved ( val, typ, md, id, sp) ) ;
1038
1056
}
1039
1057
alt info. glob_imported_names . get ( id) {
1040
1058
todo ( _, _, _, _, _) { e. sess . bug ( "Shouldn't've put a todo in." ) ; }
1041
- resolving( sp) {
1042
- ret none :: < def > ; //circularity is okay in import globs
1043
-
1044
- }
1059
+ //circularity is okay in import globs
1060
+ resolving ( sp) { ret none :: < def > ; }
1045
1061
resolved ( val, typ, md, _, _) {
1046
1062
ret alt wanted_ns {
1047
1063
ns_value. { val }
0 commit comments