@@ -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 ,
@@ -99,9 +100,9 @@ impl<'a, 'b, 'tcx> UnusedImportCheckVisitor<'a, 'b, 'tcx> {
99
100
}
100
101
}
101
102
102
- fn unused_import ( & mut self , id : ast:: NodeId ) -> & mut UnusedImport < ' a > {
103
+ fn unused_import ( & mut self , id : ast:: NodeId ) -> & mut UnusedImport {
103
104
let use_tree_id = self . base_id ;
104
- let use_tree = self . base_use_tree . unwrap ( ) ;
105
+ let use_tree = self . base_use_tree . unwrap ( ) . clone ( ) ;
105
106
let item_span = self . item_span ;
106
107
107
108
self . unused_imports . entry ( id) . or_insert_with ( || UnusedImport {
@@ -196,7 +197,7 @@ enum UnusedSpanResult {
196
197
}
197
198
198
199
fn calc_unused_spans (
199
- unused_import : & UnusedImport < ' _ > ,
200
+ unused_import : & UnusedImport ,
200
201
use_tree : & ast:: UseTree ,
201
202
use_tree_id : ast:: NodeId ,
202
203
) -> UnusedSpanResult {
@@ -286,7 +287,7 @@ impl Resolver<'_, '_> {
286
287
287
288
for import in self . potentially_unused_imports . iter ( ) {
288
289
match import. kind {
289
- _ if import. used . get ( )
290
+ _ if import. used . get ( ) . is_some ( )
290
291
|| import. expect_vis ( ) . is_public ( )
291
292
|| import. span . is_dummy ( ) =>
292
293
{
@@ -335,7 +336,7 @@ impl Resolver<'_, '_> {
335
336
336
337
for unused in visitor. unused_imports . values ( ) {
337
338
let mut fixes = Vec :: new ( ) ;
338
- let spans = match calc_unused_spans ( unused, unused. use_tree , unused. use_tree_id ) {
339
+ let spans = match calc_unused_spans ( unused, & unused. use_tree , unused. use_tree_id ) {
339
340
UnusedSpanResult :: Used => continue ,
340
341
UnusedSpanResult :: FlatUnused ( span, remove) => {
341
342
fixes. push ( ( remove, String :: new ( ) ) ) ;
@@ -482,5 +483,30 @@ impl Resolver<'_, '_> {
482
483
BuiltinLintDiagnostics :: ExternCrateNotIdiomatic { vis_span, ident_span } ,
483
484
) ;
484
485
}
486
+
487
+ let unused_imports = visitor. unused_imports ;
488
+ let mut check_redundant_imports = FxIndexSet :: default ( ) ;
489
+ for module in self . arenas . local_modules ( ) . iter ( ) {
490
+ for ( _key, resolution) in self . resolutions ( * module) . borrow ( ) . iter ( ) {
491
+ let resolution = resolution. borrow ( ) ;
492
+
493
+ if let Some ( binding) = resolution. binding
494
+ && let NameBindingKind :: Import { import, .. } = binding. kind
495
+ && let ImportKind :: Single { id, .. } = import. kind
496
+ {
497
+ if let Some ( unused_import) = unused_imports. get ( & import. root_id )
498
+ && unused_import. unused . contains ( & id)
499
+ {
500
+ continue ;
501
+ }
502
+
503
+ check_redundant_imports. insert ( import) ;
504
+ }
505
+ }
506
+ }
507
+
508
+ for import in check_redundant_imports {
509
+ self . check_for_redundant_imports ( import) ;
510
+ }
485
511
}
486
512
}
0 commit comments