11use rustc_data_structures:: fx:: { FxHashMap , FxHashSet } ;
22use rustc_errors:: Applicability ;
33use rustc_hir as hir;
4+ use rustc_hir:: def:: DefKind ;
45use rustc_hir:: def_id:: { DefId , LocalDefId } ;
5- use rustc_hir:: itemlikevisit:: ItemLikeVisitor ;
66use rustc_middle:: ty:: TyCtxt ;
77use rustc_session:: lint;
88use rustc_span:: { Span , Symbol } ;
99
1010pub fn check_crate ( tcx : TyCtxt < ' _ > ) {
11- let mut used_trait_imports = FxHashSet :: default ( ) ;
11+ let mut used_trait_imports: FxHashSet < LocalDefId > = FxHashSet :: default ( ) ;
12+
1213 for item_def_id in tcx. hir ( ) . body_owners ( ) {
1314 let imports = tcx. used_trait_imports ( item_def_id) ;
1415 debug ! ( "GatherVisitor: item_def_id={:?} with imports {:#?}" , item_def_id, imports) ;
1516 used_trait_imports. extend ( imports. iter ( ) ) ;
1617 }
1718
18- let mut visitor = CheckVisitor { tcx, used_trait_imports } ;
19-
2019 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+ }
3528 }
3629 }
3730
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) ;
4332}
4433
45- struct CheckVisitor < ' tcx > {
34+ fn check_import < ' tcx > (
4635 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+ }
5943
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 ;
7346 }
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+ } ) ;
7456}
7557
7658fn unused_crates_lint ( tcx : TyCtxt < ' _ > ) {
@@ -114,11 +96,19 @@ fn unused_crates_lint(tcx: TyCtxt<'_>) {
11496
11597 // Collect all the extern crates (in a reliable order).
11698 let mut crates_to_lint = vec ! [ ] ;
117- let mut visitor = CollectExternCrateVisitor { crates_to_lint : & mut crates_to_lint } ;
11899
119100 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+ }
122112 }
123113
124114 let extern_prelude = & tcx. resolutions ( ( ) ) . extern_prelude ;
@@ -200,10 +190,6 @@ fn unused_crates_lint(tcx: TyCtxt<'_>) {
200190 }
201191}
202192
203- struct CollectExternCrateVisitor < ' a > {
204- crates_to_lint : & ' a mut Vec < ExternCrateToLint > ,
205- }
206-
207193struct ExternCrateToLint {
208194 /// `DefId` of the extern crate
209195 def_id : DefId ,
@@ -220,22 +206,3 @@ struct ExternCrateToLint {
220206 /// about it going unused (but we should still emit idiom lints).
221207 warn_if_unused : bool ,
222208}
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