@@ -27,9 +27,10 @@ use crate::imports::ImportKind;
27
27
use crate :: module_to_string;
28
28
use crate :: Resolver ;
29
29
30
+ use crate :: NameBindingKind ;
30
31
use rustc_ast as ast;
31
32
use rustc_ast:: visit:: { self , Visitor } ;
32
- use rustc_data_structures:: fx:: { FxHashMap , FxIndexMap } ;
33
+ use rustc_data_structures:: fx:: { FxHashMap , FxIndexMap , FxIndexSet } ;
33
34
use rustc_data_structures:: unord:: UnordSet ;
34
35
use rustc_errors:: { pluralize, MultiSpan } ;
35
36
use rustc_hir:: def:: { DefKind , Res } ;
@@ -38,14 +39,14 @@ use rustc_session::lint::BuiltinLintDiagnostics;
38
39
use rustc_span:: symbol:: { kw, Ident } ;
39
40
use rustc_span:: { Span , DUMMY_SP } ;
40
41
41
- struct UnusedImport < ' a > {
42
- use_tree : & ' a ast:: UseTree ,
42
+ struct UnusedImport {
43
+ use_tree : ast:: UseTree ,
43
44
use_tree_id : ast:: NodeId ,
44
45
item_span : Span ,
45
46
unused : UnordSet < ast:: NodeId > ,
46
47
}
47
48
48
- impl < ' a > UnusedImport < ' a > {
49
+ impl UnusedImport {
49
50
fn add ( & mut self , id : ast:: NodeId ) {
50
51
self . unused . insert ( id) ;
51
52
}
@@ -54,7 +55,7 @@ impl<'a> UnusedImport<'a> {
54
55
struct UnusedImportCheckVisitor < ' a , ' b , ' tcx > {
55
56
r : & ' a mut Resolver < ' b , ' tcx > ,
56
57
/// All the (so far) unused imports, grouped path list
57
- unused_imports : FxIndexMap < ast:: NodeId , UnusedImport < ' a > > ,
58
+ unused_imports : FxIndexMap < ast:: NodeId , UnusedImport > ,
58
59
extern_crate_items : Vec < ExternCrateToLint > ,
59
60
base_use_tree : Option < & ' a ast:: UseTree > ,
60
61
base_id : ast:: NodeId ,
@@ -100,9 +101,9 @@ impl<'a, 'b, 'tcx> UnusedImportCheckVisitor<'a, 'b, 'tcx> {
100
101
}
101
102
}
102
103
103
- fn unused_import ( & mut self , id : ast:: NodeId ) -> & mut UnusedImport < ' a > {
104
+ fn unused_import ( & mut self , id : ast:: NodeId ) -> & mut UnusedImport {
104
105
let use_tree_id = self . base_id ;
105
- let use_tree = self . base_use_tree . unwrap ( ) ;
106
+ let use_tree = self . base_use_tree . unwrap ( ) . clone ( ) ;
106
107
let item_span = self . item_span ;
107
108
108
109
self . unused_imports . entry ( id) . or_insert_with ( || UnusedImport {
@@ -197,7 +198,7 @@ enum UnusedSpanResult {
197
198
}
198
199
199
200
fn calc_unused_spans (
200
- unused_import : & UnusedImport < ' _ > ,
201
+ unused_import : & UnusedImport ,
201
202
use_tree : & ast:: UseTree ,
202
203
use_tree_id : ast:: NodeId ,
203
204
) -> UnusedSpanResult {
@@ -287,7 +288,7 @@ impl Resolver<'_, '_> {
287
288
288
289
for import in self . potentially_unused_imports . iter ( ) {
289
290
match import. kind {
290
- _ if import. used . get ( )
291
+ _ if import. used . get ( ) . is_some ( )
291
292
|| import. expect_vis ( ) . is_public ( )
292
293
|| import. span . is_dummy ( ) =>
293
294
{
@@ -336,7 +337,7 @@ impl Resolver<'_, '_> {
336
337
337
338
for unused in visitor. unused_imports . values ( ) {
338
339
let mut fixes = Vec :: new ( ) ;
339
- let spans = match calc_unused_spans ( unused, unused. use_tree , unused. use_tree_id ) {
340
+ let spans = match calc_unused_spans ( unused, & unused. use_tree , unused. use_tree_id ) {
340
341
UnusedSpanResult :: Used => continue ,
341
342
UnusedSpanResult :: FlatUnused ( span, remove) => {
342
343
fixes. push ( ( remove, String :: new ( ) ) ) ;
@@ -483,5 +484,30 @@ impl Resolver<'_, '_> {
483
484
BuiltinLintDiagnostics :: ExternCrateNotIdiomatic { vis_span, ident_span } ,
484
485
) ;
485
486
}
487
+
488
+ let unused_imports = visitor. unused_imports ;
489
+ let mut check_redundant_imports = FxIndexSet :: default ( ) ;
490
+ for module in self . arenas . local_modules ( ) . iter ( ) {
491
+ for ( _key, resolution) in self . resolutions ( * module) . borrow ( ) . iter ( ) {
492
+ let resolution = resolution. borrow ( ) ;
493
+
494
+ if let Some ( binding) = resolution. binding
495
+ && let NameBindingKind :: Import { import, .. } = binding. kind
496
+ && let ImportKind :: Single { id, .. } = import. kind
497
+ {
498
+ if let Some ( unused_import) = unused_imports. get ( & import. root_id )
499
+ && unused_import. unused . contains ( & id)
500
+ {
501
+ continue ;
502
+ }
503
+
504
+ check_redundant_imports. insert ( import) ;
505
+ }
506
+ }
507
+ }
508
+
509
+ for import in check_redundant_imports {
510
+ self . check_for_redundant_imports ( import) ;
511
+ }
486
512
}
487
513
}
0 commit comments