@@ -27,6 +27,7 @@ import std::list::list;
27
27
import std:: list:: nil;
28
28
import std:: list:: cons;
29
29
import std:: option;
30
+ import std:: option:: is_none;
30
31
import std:: option:: some;
31
32
import std:: option:: none;
32
33
import std:: str;
@@ -89,7 +90,6 @@ tag mod_index_entry {
89
90
mie_item ( @ast:: item) ;
90
91
mie_native_item ( @ast:: native_item) ;
91
92
mie_tag_variant ( @ast:: item /* tag item */ , uint /* variant index */ ) ;
92
-
93
93
}
94
94
95
95
type mod_index = hashmap [ ident, list[ mod_index_entry] ] ;
@@ -117,6 +117,7 @@ type env =
117
117
hashmap[ ast:: node_id, @indexed_mod] mod_map ,
118
118
hashmap[ def_id, ident[ ] ] ext_map ,
119
119
ext_hash ext_cache ,
120
+ mutable tup( str, scope) [ ] reported,
120
121
session sess) ;
121
122
122
123
@@ -136,6 +137,7 @@ fn resolve_crate(session sess, &ast_map::map amap, @ast::crate crate)
136
137
mod_map=new_int_hash[ @indexed_mod] ( ) ,
137
138
ext_map=new_def_hash[ ident[ ] ] ( ) ,
138
139
ext_cache=new_ext_hash( ) ,
140
+ mutable reported=~[ ] ,
139
141
sess=sess) ;
140
142
map_crate( e, crate ) ;
141
143
resolve_imports ( * e) ;
@@ -386,7 +388,7 @@ fn follow_import(&env e, &scopes sc, &ident[] path, &span sp)
386
388
auto i = 1 u;
387
389
while ( true && option:: is_some( dcur) ) {
388
390
if ( i == path_len) { break ; }
389
- dcur = lookup_in_mod_strict( e, option:: get( dcur) ,
391
+ dcur = lookup_in_mod_strict( e, sc , option:: get( dcur) ,
390
392
sp, path. ( i) , ns_module, outside) ;
391
393
i += 1 u;
392
394
}
@@ -424,7 +426,7 @@ fn resolve_constr(@env e, node_id id, &@ast::constr c, &scopes sc,
424
426
}
425
427
426
428
// Import resolution
427
- fn resolve_import( & env e, & @ast:: view_item it, scopes sc ) {
429
+ fn resolve_import( & env e, & @ast:: view_item it, & scopes sc_in ) {
428
430
auto defid;
429
431
auto ids;
430
432
auto name;
@@ -439,11 +441,10 @@ fn resolve_import(&env e, &@ast::view_item it, scopes sc) {
439
441
auto n_idents = ivec:: len( ids) ;
440
442
auto end_id = ids. ( n_idents - 1 u) ;
441
443
// Ignore the current scope if this import would shadow itself.
442
- if ( str:: eq( name, ids. ( 0 ) ) ) {
443
- sc = std:: list:: cdr( sc) ;
444
- }
444
+ auto sc = if str :: eq( name, ids. ( 0 ) ) { std:: list:: cdr( sc_in) }
445
+ else { sc_in } ;
445
446
if ( n_idents == 1 u) {
446
- register( e, defid, it. span, end_id,
447
+ register( e, defid, it. span, end_id, sc_in ,
447
448
lookup_in_scope( e, sc, it. span, end_id, ns_value) ,
448
449
lookup_in_scope( e, sc, it. span, end_id, ns_type) ,
449
450
lookup_in_scope( e, sc, it. span, end_id, ns_module) ) ;
@@ -454,15 +455,15 @@ fn resolve_import(&env e, &@ast::view_item it, scopes sc) {
454
455
dcur
455
456
}
456
457
case ( none) {
457
- unresolved_err( e, it. span, ids. ( 0 ) , ns_name( ns_module) ) ;
458
+ unresolved_err( e, sc , it. span, ids. ( 0 ) , ns_name( ns_module) ) ;
458
459
remove_if_unresolved( e. imports, defid. _1) ;
459
460
ret ( ) // FIXME (issue #521)
460
461
}
461
462
} ;
462
463
auto i = 1 u;
463
464
while ( true ) {
464
465
if ( i == n_idents - 1 u) {
465
- register( e, defid, it. span, end_id,
466
+ register( e, defid, it. span, end_id, sc_in ,
466
467
lookup_in_mod( e, dcur, it. span, end_id, ns_value,
467
468
outside) ,
468
469
lookup_in_mod( e, dcur, it. span, end_id, ns_type,
@@ -478,7 +479,7 @@ fn resolve_import(&env e, &@ast::view_item it, scopes sc) {
478
479
dcur
479
480
}
480
481
case ( none) {
481
- unresolved_err( e, it. span, ids. ( i) ,
482
+ unresolved_err( e, sc , it. span, ids. ( i) ,
482
483
ns_name( ns_module) ) ;
483
484
remove_if_unresolved( e. imports, defid. _1) ;
484
485
ret ( ) // FIXME (issue #521)
@@ -488,12 +489,11 @@ fn resolve_import(&env e, &@ast::view_item it, scopes sc) {
488
489
}
489
490
}
490
491
}
491
- fn register( & env e, def_id defid, & span sp, & ident name,
492
+ fn register( & env e, def_id defid, & span sp, & ident name, & scopes sc ,
492
493
& option:: t[ def] val, & option:: t[ def] typ,
493
494
& option:: t[ def] md) {
494
- if ( option:: is_none( val) && option:: is_none( typ) &&
495
- option:: is_none( md) ) {
496
- unresolved_err( e, sp, name, "import" ) ;
495
+ if is_none( val) && is_none( typ) && is_none( md) {
496
+ unresolved_err( e, sc, sp, name, "import" ) ;
497
497
} else {
498
498
e. imports. insert( defid. _1, resolved( val, typ, md) ) ;
499
499
}
@@ -524,7 +524,28 @@ fn ns_name(namespace ns) -> str {
524
524
}
525
525
}
526
526
527
- fn unresolved_err( & env e, & span sp, & ident name, & str kind) {
527
+ fn unresolved_err( & env e, & scopes sc, & span sp, & ident name, & str kind) {
528
+ fn find_fn_or_mod_scope( scopes sc) -> scope {
529
+ while true {
530
+ alt sc {
531
+ cons( ?cur, ?rest) {
532
+ alt cur {
533
+ scope_crate | scope_fn( _, _) |
534
+ scope_item ( @{ node : ast:: item_mod( _) , _} ) {
535
+ ret cur;
536
+ }
537
+ _ { sc = * rest; }
538
+ }
539
+ }
540
+ }
541
+ }
542
+ fail;
543
+ }
544
+ auto err_scope = find_fn_or_mod_scope( sc) ;
545
+ for ( tup( str , scope) rs in e. reported) {
546
+ if str :: eq( rs. _0, name) && err_scope == rs. _1 { ret; }
547
+ }
548
+ e. reported += ~[ tup( name, err_scope) ] ;
528
549
e. sess. span_err( sp, mk_unresolved_msg( name, kind) ) ;
529
550
}
530
551
@@ -555,7 +576,7 @@ fn lookup_path_strict(&env e, &scopes sc, &span sp, &ast::path_ pth,
555
576
auto i = 1 u;
556
577
while ( i < n_idents && option:: is_some ( dcur ) ) {
557
578
auto curns = if ( n_idents == i + 1 u) { ns } else { ns_module } ;
558
- dcur = lookup_in_mod_strict ( e, option:: get ( dcur) ,
579
+ dcur = lookup_in_mod_strict ( e, sc , option:: get ( dcur) ,
559
580
sp, pth. idents . ( i) , curns, outside) ;
560
581
i += 1 u;
561
582
}
@@ -566,7 +587,7 @@ fn lookup_in_scope_strict(&env e, scopes sc, &span sp, &ident name,
566
587
namespace ns) -> option:: t [ def ] {
567
588
alt ( lookup_in_scope ( e, sc, sp, name, ns) ) {
568
589
case ( none) {
569
- unresolved_err ( e, sp, name, ns_name ( ns) ) ;
590
+ unresolved_err ( e, sc , sp, name, ns_name ( ns) ) ;
570
591
ret none;
571
592
}
572
593
case ( some ( ?d) ) { ret some ( d) ; }
@@ -662,7 +683,7 @@ fn lookup_in_scope(&env e, scopes sc, &span sp, &ident name, namespace ns) ->
662
683
case ( nil) { ret none[ def] ; }
663
684
case ( cons ( ?hd, ?tl) ) {
664
685
auto fnd = in_scope ( e, sp, name, hd, ns) ;
665
- if ( !option :: is_none ( fnd) ) {
686
+ if ( !is_none ( fnd) ) {
666
687
auto df = option:: get ( fnd) ;
667
688
if ( left_fn && def_is_local ( df) ||
668
689
left_fn_level2 && def_is_obj_field ( df)
@@ -713,13 +734,13 @@ fn lookup_in_pat(&ident name, &ast::pat pat) -> option::t[def] {
713
734
case ( ast:: pat_tag ( _, ?pats) ) {
714
735
for ( @ast:: pat p in pats) {
715
736
auto found = lookup_in_pat( name, * p) ;
716
- if ( !option :: is_none( found) ) { ret found; }
737
+ if ( !is_none( found) ) { ret found; }
717
738
}
718
739
}
719
740
case ( ast:: pat_rec( ?fields, _) ) {
720
741
for ( ast:: field_pat f in fields) {
721
742
auto found = lookup_in_pat( name, * f. pat) ;
722
- if ( !option :: is_none( found) ) { ret found; }
743
+ if ( !is_none( found) ) { ret found; }
723
744
}
724
745
}
725
746
case ( ast:: pat_box( ?inner) ) { ret lookup_in_pat( name, * inner) ; }
@@ -793,7 +814,7 @@ fn lookup_in_block(&ident name, &ast::block_ b, namespace ns) ->
793
814
case ( _) {
794
815
if ( str:: eq( it. ident, name) ) {
795
816
auto found = found_def_item( it, ns) ;
796
- if ( !option :: is_none( found) ) {
817
+ if ( !is_none( found) ) {
797
818
ret found;
798
819
}
799
820
}
@@ -861,11 +882,11 @@ fn found_def_item(&@ast::item i, namespace ns) -> option::t[def] {
861
882
ret none[ def] ;
862
883
}
863
884
864
- fn lookup_in_mod_strict( & env e, def m, & span sp, & ident name, namespace ns ,
865
- dir dr) -> option:: t[ def] {
885
+ fn lookup_in_mod_strict( & env e, & scopes sc , def m, & span sp, & ident name,
886
+ namespace ns , dir dr) -> option:: t[ def] {
866
887
alt ( lookup_in_mod( e, m, sp, name, ns, dr) ) {
867
888
case ( none) {
868
- unresolved_err( e, sp, name, ns_name( ns) ) ;
889
+ unresolved_err( e, sc , sp, name, ns_name( ns) ) ;
869
890
ret none;
870
891
}
871
892
case ( some( ?d) ) { ret some( d) ; }
@@ -879,11 +900,11 @@ fn lookup_in_mod(&env e, &def m, &span sp, &ident name, namespace ns,
879
900
// examining a module in an external crate
880
901
881
902
auto cached = e. ext_cache. find( tup( defid, name, ns) ) ;
882
- if ( !option :: is_none( cached) ) { ret cached; }
903
+ if ( !is_none( cached) ) { ret cached; }
883
904
auto path = ~[ name] ;
884
905
if ( defid. _1 != -1 ) { path = e. ext_map. get( defid) + path; }
885
906
auto fnd = lookup_external( e, defid. _0, path, ns) ;
886
- if ( !option :: is_none( fnd) ) {
907
+ if ( !is_none( fnd) ) {
887
908
e. ext_cache. insert( tup( defid, name, ns) , option:: get( fnd) ) ;
888
909
}
889
910
ret fnd;
@@ -958,7 +979,7 @@ fn lookup_in_local_mod(&env e, node_id node_id, &span sp, &ident id,
958
979
case ( nil) { break ; }
959
980
case ( cons( ?hd, ?tl) ) {
960
981
auto found = lookup_in_mie( e, hd, ns) ;
961
- if ( !option :: is_none( found) ) { ret found; }
982
+ if ( !is_none( found) ) { ret found; }
962
983
lst = * tl;
963
984
}
964
985
}
@@ -1196,17 +1217,17 @@ fn check_mod_name(&env e, &ident name, list[mod_index_entry] entries) {
1196
1217
while ( true ) {
1197
1218
alt ( entries) {
1198
1219
case ( cons ( ?entry, ?rest) ) {
1199
- if ( !option :: is_none ( lookup_in_mie ( e, entry, ns_value) ) ) {
1220
+ if ( !is_none ( lookup_in_mie ( e, entry, ns_value) ) ) {
1200
1221
if ( saw_value) {
1201
1222
dup ( e, mie_span ( entry) , "" , name) ;
1202
1223
} else { saw_value = true ; }
1203
1224
}
1204
- if ( !option :: is_none ( lookup_in_mie ( e, entry, ns_type) ) ) {
1225
+ if ( !is_none ( lookup_in_mie ( e, entry, ns_type) ) ) {
1205
1226
if ( saw_type) {
1206
1227
dup ( e, mie_span ( entry) , "type " , name) ;
1207
1228
} else { saw_type = true ; }
1208
1229
}
1209
- if ( !option :: is_none ( lookup_in_mie ( e, entry, ns_module) ) ) {
1230
+ if ( !is_none ( lookup_in_mie ( e, entry, ns_module) ) ) {
1210
1231
if ( saw_mod) {
1211
1232
dup ( e, mie_span ( entry) , "module " , name) ;
1212
1233
} else { saw_mod = true ; }
@@ -1283,8 +1304,7 @@ fn check_arm(@env e, &ast::arm a, &() x, &vt[()] v) {
1283
1304
"inconsistent number of bindings" ) ;
1284
1305
} else {
1285
1306
for ( ident name in ch. seen) {
1286
- if ( option:: is_none ( ivec:: find ( bind str:: eq ( name, _) ,
1287
- seen0) ) ) {
1307
+ if ( is_none ( ivec:: find ( bind str:: eq ( name, _) , seen0) ) ) {
1288
1308
// Fight the alias checker
1289
1309
auto name_ = name;
1290
1310
e. sess . span_err
0 commit comments