@@ -50,7 +50,9 @@ tag import_state {
50
50
resolving ( span) ;
51
51
resolved ( option:: t<def>, /* value */
52
52
option:: t<def>, /* type */
53
- option:: t<def>) ; /* module */
53
+ option:: t<def>, /* module */
54
+ /* used for reporting unused import warning */
55
+ ast:: ident, codemap:: span) ;
54
56
}
55
57
56
58
type ext_hash = hashmap < { did: def_id , ident : str , ns : namespace } , def > ;
@@ -106,6 +108,7 @@ type env =
106
108
mod_map : hashmap < ast:: node_id , @indexed_mod > ,
107
109
ext_map : hashmap < def_id , [ ident ] > ,
108
110
ext_cache : ext_hash ,
111
+ mutable used_imports: option:: t < [ ast:: node_id ] > ,
109
112
mutable reported: [ { ident: str , sc : scope } ] ,
110
113
mutable currently_resolving: node_id ,
111
114
sess : session } ;
@@ -127,18 +130,20 @@ fn resolve_crate(sess: session, amap: ast_map::map, crate: @ast::crate) ->
127
130
mod_map: new_int_hash :: < @indexed_mod > ( ) ,
128
131
ext_map: new_def_hash :: < [ ident ] > ( ) ,
129
132
ext_cache: new_ext_hash ( ) ,
133
+ mutable used_imports: none,
130
134
mutable reported: [ ] ,
131
135
mutable currently_resolving: -1 ,
132
136
sess: sess} ;
133
137
map_crate ( e, crate ) ;
134
138
resolve_imports ( * e) ;
135
139
check_for_collisions ( e, * crate ) ;
136
140
check_bad_exports ( e) ;
141
+ e. used_imports = some ( [ ] ) ;
137
142
resolve_names ( e, crate ) ;
143
+ check_unused_imports ( e) ;
138
144
ret { def_map : e. def_map , ext_map : e. ext_map } ;
139
145
}
140
146
141
-
142
147
// Locate all modules and imports and index them, so that the next passes can
143
148
// resolve through them.
144
149
fn map_crate ( e : @env , c : @ast:: crate ) {
@@ -239,12 +244,26 @@ fn resolve_imports(e: env) {
239
244
todo( node_id, name, path, span, scopes) {
240
245
resolve_import ( e, local_def ( node_id) , name, path, span, scopes) ;
241
246
}
242
- resolved ( _, _, _) { }
247
+ resolved ( _, _, _, _ , _ ) { }
243
248
}
244
249
} ;
245
250
e. sess . abort_if_errors ( ) ;
246
251
}
247
252
253
+ fn check_unused_imports ( e : @env ) {
254
+ let used = option:: get ( e. used_imports ) ;
255
+ e. imports . items { |k, v|
256
+ alt v {
257
+ resolved( val, ty, md, name, sp) {
258
+ if !vec:: member ( k, used) {
259
+ e. sess . span_warn ( sp, "unused import " + name) ;
260
+ }
261
+ }
262
+ _ { }
263
+ }
264
+ } ;
265
+ }
266
+
248
267
fn resolve_names ( e : @env , c : @ast:: crate ) {
249
268
let v =
250
269
@{ visit_native_item: visit_native_item_with_scope,
@@ -439,7 +458,7 @@ fn resolve_import(e: env, defid: ast::def_id, name: ast::ident,
439
458
if is_none ( val) && is_none ( typ) && is_none ( md) {
440
459
unresolved_err ( e, sc, sp, name, "import" ) ;
441
460
} else {
442
- e. imports . insert ( id, resolved ( val, typ, md) ) ;
461
+ e. imports . insert ( id, resolved ( val, typ, md, name , sp ) ) ;
443
462
}
444
463
}
445
464
// This function has cleanup code at the end. Do not return without going
@@ -483,8 +502,8 @@ fn resolve_import(e: env, defid: ast::def_id, name: ast::ident,
483
502
// resolved state, to avoid having it reported later as a cyclic
484
503
// import
485
504
alt e. imports . find ( defid. node ) {
486
- some ( resolving ( _ ) ) {
487
- e. imports . insert ( defid. node , resolved ( none, none, none) ) ;
505
+ some ( resolving ( sp ) ) {
506
+ e. imports . insert ( defid. node , resolved ( none, none, none, "" , sp ) ) ;
488
507
}
489
508
_ { }
490
509
}
@@ -931,7 +950,14 @@ fn lookup_import(e: env, defid: def_id, ns: namespace) -> option::t<def> {
931
950
}
932
951
ret none;
933
952
}
934
- resolved ( val, typ, md) {
953
+ resolved ( val, typ, md, _, _) {
954
+ alt e. used_imports {
955
+ none. { }
956
+ some ( lst_) {
957
+ let lst = lst_ + [ defid. node ] ;
958
+ e. used_imports = option:: some ( lst) ;
959
+ }
960
+ }
935
961
ret alt ns { ns_value. { val } ns_type. { typ } ns_module. { md } } ;
936
962
}
937
963
}
@@ -1008,15 +1034,15 @@ fn lookup_glob_in_mod(e: env, info: @indexed_mod, sp: span, id: ident,
1008
1034
let val = per_ns ( e, info, sp, id, ns_value, dr) ;
1009
1035
let typ = per_ns ( e, info, sp, id, ns_type, dr) ;
1010
1036
let md = per_ns ( e, info, sp, id, ns_module, dr) ;
1011
- info. glob_imported_names . insert ( id, resolved ( val, typ, md) ) ;
1037
+ info. glob_imported_names . insert ( id, resolved ( val, typ, md, id , sp ) ) ;
1012
1038
}
1013
1039
alt info. glob_imported_names . get ( id) {
1014
1040
todo( _, _, _, _, _) { e. sess . bug ( "Shouldn't've put a todo in." ) ; }
1015
1041
resolving( sp) {
1016
1042
ret none :: < def > ; //circularity is okay in import globs
1017
1043
1018
1044
}
1019
- resolved( val, typ, md) {
1045
+ resolved( val, typ, md, _ , _ ) {
1020
1046
ret alt wanted_ns {
1021
1047
ns_value. { val }
1022
1048
ns_type. { typ }
0 commit comments