@@ -107,6 +107,7 @@ type env =
107
107
ext_map : hashmap < def_id , [ ident ] > ,
108
108
ext_cache : ext_hash ,
109
109
mutable reported: [ { ident: str , sc : scope } ] ,
110
+ mutable currently_resolving: node_id ,
110
111
sess : session } ;
111
112
112
113
@@ -127,6 +128,7 @@ fn resolve_crate(sess: session, amap: ast_map::map, crate: @ast::crate) ->
127
128
ext_map: new_def_hash :: < [ ident ] > ( ) ,
128
129
ext_cache: new_ext_hash ( ) ,
129
130
mutable reported: [ ] ,
131
+ mutable currently_resolving: -1 ,
130
132
sess: sess} ;
131
133
map_crate ( e, crate ) ;
132
134
resolve_imports ( * e) ;
@@ -218,11 +220,6 @@ fn map_crate(e: @env, c: @ast::crate) {
218
220
}
219
221
}
220
222
alt vi. node {
221
-
222
-
223
-
224
-
225
-
226
223
//if it really is a glob import, that is
227
224
ast:: view_item_import_glob ( path, _) {
228
225
let imp = follow_import ( * e, sc, path, vi. span ) ;
@@ -435,73 +432,62 @@ fn resolve_constr(e: @env, c: @ast::constr, sc: scopes, _v: vt<scopes>) {
435
432
436
433
// Import resolution
437
434
fn resolve_import ( e : env , defid : ast:: def_id , name : ast:: ident ,
438
- ids : [ ast:: ident ] , sp : codemap:: span , sc_in : scopes ) {
435
+ ids : [ ast:: ident ] , sp : codemap:: span , sc : scopes ) {
436
+ fn register ( e : env , id : node_id , sc : scopes , sp : codemap:: span ,
437
+ name : ast:: ident , lookup : block ( namespace ) -> option:: t < def > ) {
438
+ let val = lookup ( ns_value) , typ = lookup ( ns_type) ,
439
+ md = lookup ( ns_module) ;
440
+ if is_none ( val) && is_none ( typ) && is_none ( md) {
441
+ unresolved_err ( e, sc, sp, name, "import" ) ;
442
+ } else {
443
+ e. imports . insert ( id, resolved ( val, typ, md) ) ;
444
+ }
445
+ }
446
+ // This function has cleanup code at the end. Do not return without going
447
+ // through that.
439
448
e. imports . insert ( defid. node , resolving ( sp) ) ;
449
+ let previously_resolving = e. currently_resolving ;
450
+ e. currently_resolving = defid. node ;
440
451
let n_idents = vec:: len ( ids) ;
441
452
let end_id = ids[ n_idents - 1 u] ;
442
- // Ignore the current scope if this import would shadow itself.
443
- let sc =
444
- if str:: eq ( name, ids[ 0 ] ) { std:: list:: cdr ( sc_in) } else { sc_in } ;
445
453
if n_idents == 1 u {
446
- register ( e, defid, sp, end_id, sc_in,
447
- lookup_in_scope ( e, sc, sp, end_id, ns_value) ,
448
- lookup_in_scope ( e, sc, sp, end_id, ns_type) ,
449
- lookup_in_scope ( e, sc, sp, end_id, ns_module) ) ;
450
- remove_if_unresolved ( e. imports , defid. node ) ;
454
+ register ( e, defid. node , sc, sp, name,
455
+ { |ns| lookup_in_scope ( e, sc, sp, end_id, ns) } ) ;
451
456
} else {
452
- let dcur =
453
- alt lookup_in_scope ( e, sc, sp, ids[ 0 ] , ns_module) {
454
- some ( dcur) { dcur }
455
- none. {
456
- unresolved_err ( e, sc, sp, ids[ 0 ] , ns_name ( ns_module) ) ;
457
- remove_if_unresolved ( e. imports , defid. node ) ;
458
- ret;
459
- }
460
- } ;
461
- let i = 1 u;
462
- while true {
463
- if i == n_idents - 1 u {
464
- register ( e, defid, sp, end_id, sc_in,
465
- lookup_in_mod ( e, dcur, sp, end_id, ns_value,
466
- outside) ,
467
- lookup_in_mod ( e, dcur, sp, end_id, ns_type, outside) ,
468
- lookup_in_mod ( e, dcur, sp, end_id, ns_module,
469
- outside) ) ;
470
- remove_if_unresolved ( e. imports , defid. node ) ;
471
- break ;
472
- } else {
473
- dcur = alt lookup_in_mod ( e, dcur, sp, ids[ i] , ns_module,
474
- outside) {
475
- some ( dcur) { dcur }
476
- none. {
477
- unresolved_err ( e, sc, sp, ids[ i] , ns_name ( ns_module) ) ;
478
- remove_if_unresolved ( e. imports , defid. node ) ;
479
- ret;
480
- }
481
- } ;
482
- i += 1 u;
457
+ alt lookup_in_scope ( e, sc, sp, ids[ 0 ] , ns_module) {
458
+ none. { unresolved_err ( e, sc, sp, ids[ 0 ] , ns_name ( ns_module) ) ; }
459
+ some ( dcur_) {
460
+ let dcur = dcur_, i = 1 u;
461
+ while true {
462
+ if i == n_idents - 1 u {
463
+ register ( e, defid. node , sc, sp, name, { |ns|
464
+ lookup_in_mod ( e, dcur, sp, end_id, ns, outside)
465
+ } ) ;
466
+ break ;
467
+ } else {
468
+ dcur = alt lookup_in_mod ( e, dcur, sp, ids[ i] , ns_module,
469
+ outside) {
470
+ some ( dcur) { dcur }
471
+ none. {
472
+ unresolved_err ( e, sc, sp, ids[ i] , ns_name ( ns_module) ) ;
473
+ break ;
474
+ }
475
+ } ;
476
+ i += 1 u;
477
+ }
483
478
}
479
+ }
484
480
}
485
481
}
486
- fn register ( e : env , defid : def_id , sp : span , name : ident , sc : scopes ,
487
- val : option:: t < def > , typ : option:: t < def > ,
488
- md : option:: t < def > ) {
489
- if is_none ( val) && is_none ( typ) && is_none ( md) {
490
- unresolved_err ( e, sc, sp, name, "import" ) ;
491
- } else { e. imports . insert ( defid. node , resolved ( val, typ, md) ) ; }
492
- }
493
- fn remove_if_unresolved ( imports : hashmap < ast:: node_id , import_state > ,
494
- node_id : ast:: node_id ) {
495
-
496
- // If we couldn't resolve the import, don't leave it in a partially
497
- // resolved state, to avoid having it reported later as a cyclic
498
- // import
499
- if imports. contains_key ( node_id) {
500
- alt imports. get ( node_id) {
501
- resolving ( _) { imports. remove ( node_id) ; }
502
- _ { }
503
- }
504
- }
482
+ e. currently_resolving = previously_resolving;
483
+ // If we couldn't resolve the import, don't leave it in a partially
484
+ // resolved state, to avoid having it reported later as a cyclic
485
+ // import
486
+ alt e. imports . find ( defid. node ) {
487
+ some ( resolving ( _) ) {
488
+ e. imports . insert ( defid. node , resolved ( none, none, none) ) ;
489
+ }
490
+ _ { }
505
491
}
506
492
}
507
493
@@ -937,7 +923,13 @@ fn lookup_import(e: env, defid: def_id, ns: namespace) -> option::t<def> {
937
923
resolve_import ( e, local_def ( node_id) , name, path, span, scopes) ;
938
924
ret lookup_import ( e, defid, ns) ;
939
925
}
940
- resolving ( sp) { e. sess . span_err ( sp, "cyclic import" ) ; ret none; }
926
+ resolving ( sp) {
927
+ // Imports are simply ignored when resolving themselves.
928
+ if e. currently_resolving != defid. node {
929
+ e. sess . span_err ( sp, "cyclic import" ) ;
930
+ }
931
+ ret none;
932
+ }
941
933
resolved ( val, typ, md) {
942
934
ret alt ns { ns_value. { val } ns_type. { typ } ns_module. { md } } ;
943
935
}
0 commit comments