1
1
use rustc_data_structures:: fx:: { FxHashMap , FxHashSet } ;
2
2
use rustc_errors:: Applicability ;
3
3
use rustc_hir as hir;
4
+ use rustc_hir:: def:: DefKind ;
4
5
use rustc_hir:: def_id:: { DefId , LocalDefId } ;
5
- use rustc_hir:: itemlikevisit:: ItemLikeVisitor ;
6
6
use rustc_middle:: ty:: TyCtxt ;
7
7
use rustc_session:: lint;
8
8
use rustc_span:: { Span , Symbol } ;
9
9
10
10
pub fn check_crate ( tcx : TyCtxt < ' _ > ) {
11
- let mut used_trait_imports = FxHashSet :: default ( ) ;
11
+ let mut used_trait_imports: FxHashSet < LocalDefId > = FxHashSet :: default ( ) ;
12
+
12
13
for item_def_id in tcx. hir ( ) . body_owners ( ) {
13
14
let imports = tcx. used_trait_imports ( item_def_id) ;
14
15
debug ! ( "GatherVisitor: item_def_id={:?} with imports {:#?}" , item_def_id, imports) ;
15
16
used_trait_imports. extend ( imports. iter ( ) ) ;
16
17
}
17
18
18
- let mut visitor = CheckVisitor { tcx, used_trait_imports } ;
19
-
20
19
for id in tcx. hir ( ) . items ( ) {
21
- let item = tcx. hir ( ) . item ( id) ;
22
- visitor. visit_item ( item) ;
23
- }
24
-
25
- unused_crates_lint ( tcx) ;
26
- }
27
-
28
- impl < ' tcx > ItemLikeVisitor < ' _ > for CheckVisitor < ' tcx > {
29
- fn visit_item ( & mut self , item : & hir:: Item < ' _ > ) {
30
- if item. vis . node . is_pub ( ) || item. span . is_dummy ( ) {
31
- return ;
32
- }
33
- if let hir:: ItemKind :: Use ( path, _) = item. kind {
34
- self . check_import ( item. item_id ( ) , path. span ) ;
20
+ if matches ! ( tcx. hir( ) . def_kind( id. def_id) , DefKind :: Use ) {
21
+ let item = tcx. hir ( ) . item ( id) ;
22
+ if item. vis . node . is_pub ( ) || item. span . is_dummy ( ) {
23
+ continue ;
24
+ }
25
+ if let hir:: ItemKind :: Use ( path, _) = item. kind {
26
+ check_import ( tcx, & mut used_trait_imports, item. item_id ( ) , path. span ) ;
27
+ }
35
28
}
36
29
}
37
30
38
- fn visit_trait_item ( & mut self , _trait_item : & hir:: TraitItem < ' _ > ) { }
39
-
40
- fn visit_impl_item ( & mut self , _impl_item : & hir:: ImplItem < ' _ > ) { }
41
-
42
- fn visit_foreign_item ( & mut self , _foreign_item : & hir:: ForeignItem < ' _ > ) { }
31
+ unused_crates_lint ( tcx) ;
43
32
}
44
33
45
- struct CheckVisitor < ' tcx > {
34
+ fn check_import < ' tcx > (
46
35
tcx : TyCtxt < ' tcx > ,
47
- used_trait_imports : FxHashSet < LocalDefId > ,
48
- }
49
-
50
- impl < ' tcx > CheckVisitor < ' tcx > {
51
- fn check_import ( & self , item_id : hir:: ItemId , span : Span ) {
52
- if !self . tcx . maybe_unused_trait_import ( item_id. def_id ) {
53
- return ;
54
- }
55
-
56
- if self . used_trait_imports . contains ( & item_id. def_id ) {
57
- return ;
58
- }
36
+ used_trait_imports : & mut FxHashSet < LocalDefId > ,
37
+ item_id : hir:: ItemId ,
38
+ span : Span ,
39
+ ) {
40
+ if !tcx. maybe_unused_trait_import ( item_id. def_id ) {
41
+ return ;
42
+ }
59
43
60
- self . tcx . struct_span_lint_hir (
61
- lint:: builtin:: UNUSED_IMPORTS ,
62
- item_id. hir_id ( ) ,
63
- span,
64
- |lint| {
65
- let msg = if let Ok ( snippet) = self . tcx . sess . source_map ( ) . span_to_snippet ( span) {
66
- format ! ( "unused import: `{}`" , snippet)
67
- } else {
68
- "unused import" . to_owned ( )
69
- } ;
70
- lint. build ( & msg) . emit ( ) ;
71
- } ,
72
- ) ;
44
+ if used_trait_imports. contains ( & item_id. def_id ) {
45
+ return ;
73
46
}
47
+
48
+ tcx. struct_span_lint_hir ( lint:: builtin:: UNUSED_IMPORTS , item_id. hir_id ( ) , span, |lint| {
49
+ let msg = if let Ok ( snippet) = tcx. sess . source_map ( ) . span_to_snippet ( span) {
50
+ format ! ( "unused import: `{}`" , snippet)
51
+ } else {
52
+ "unused import" . to_owned ( )
53
+ } ;
54
+ lint. build ( & msg) . emit ( ) ;
55
+ } ) ;
74
56
}
75
57
76
58
fn unused_crates_lint ( tcx : TyCtxt < ' _ > ) {
@@ -114,11 +96,19 @@ fn unused_crates_lint(tcx: TyCtxt<'_>) {
114
96
115
97
// Collect all the extern crates (in a reliable order).
116
98
let mut crates_to_lint = vec ! [ ] ;
117
- let mut visitor = CollectExternCrateVisitor { crates_to_lint : & mut crates_to_lint } ;
118
99
119
100
for id in tcx. hir ( ) . items ( ) {
120
- let item = tcx. hir ( ) . item ( id) ;
121
- visitor. visit_item ( item) ;
101
+ if matches ! ( tcx. hir( ) . def_kind( id. def_id) , DefKind :: ExternCrate ) {
102
+ let item = tcx. hir ( ) . item ( id) ;
103
+ if let hir:: ItemKind :: ExternCrate ( orig_name) = item. kind {
104
+ crates_to_lint. push ( ExternCrateToLint {
105
+ def_id : item. def_id . to_def_id ( ) ,
106
+ span : item. span ,
107
+ orig_name,
108
+ warn_if_unused : !item. ident . as_str ( ) . starts_with ( '_' ) ,
109
+ } ) ;
110
+ }
111
+ }
122
112
}
123
113
124
114
let extern_prelude = & tcx. resolutions ( ( ) ) . extern_prelude ;
@@ -200,10 +190,6 @@ fn unused_crates_lint(tcx: TyCtxt<'_>) {
200
190
}
201
191
}
202
192
203
- struct CollectExternCrateVisitor < ' a > {
204
- crates_to_lint : & ' a mut Vec < ExternCrateToLint > ,
205
- }
206
-
207
193
struct ExternCrateToLint {
208
194
/// `DefId` of the extern crate
209
195
def_id : DefId ,
@@ -220,22 +206,3 @@ struct ExternCrateToLint {
220
206
/// about it going unused (but we should still emit idiom lints).
221
207
warn_if_unused : bool ,
222
208
}
223
-
224
- impl < ' a , ' v > ItemLikeVisitor < ' v > for CollectExternCrateVisitor < ' a > {
225
- fn visit_item ( & mut self , item : & hir:: Item < ' _ > ) {
226
- if let hir:: ItemKind :: ExternCrate ( orig_name) = item. kind {
227
- self . crates_to_lint . push ( ExternCrateToLint {
228
- def_id : item. def_id . to_def_id ( ) ,
229
- span : item. span ,
230
- orig_name,
231
- warn_if_unused : !item. ident . as_str ( ) . starts_with ( '_' ) ,
232
- } ) ;
233
- }
234
- }
235
-
236
- fn visit_trait_item ( & mut self , _trait_item : & hir:: TraitItem < ' _ > ) { }
237
-
238
- fn visit_impl_item ( & mut self , _impl_item : & hir:: ImplItem < ' _ > ) { }
239
-
240
- fn visit_foreign_item ( & mut self , _foreign_item : & hir:: ForeignItem < ' _ > ) { }
241
- }
0 commit comments