@@ -39,6 +39,7 @@ use rustc_session::lint::BuiltinLintDiag;
39
39
use rustc_span:: symbol:: { kw, Ident } ;
40
40
use rustc_span:: { Span , DUMMY_SP } ;
41
41
42
+ #[ derive( Debug ) ]
42
43
struct UnusedImport {
43
44
use_tree : ast:: UseTree ,
44
45
use_tree_id : ast:: NodeId ,
@@ -190,6 +191,40 @@ impl<'a, 'b, 'tcx> Visitor<'a> for UnusedImportCheckVisitor<'a, 'b, 'tcx> {
190
191
}
191
192
}
192
193
194
+ struct ImportVisitor {
195
+ unused_import : Option < UnusedImport > ,
196
+ root_node_id : ast:: NodeId ,
197
+ node_id : ast:: NodeId ,
198
+ item_span : Span ,
199
+ }
200
+
201
+ impl Visitor < ' _ > for ImportVisitor {
202
+ fn visit_item ( & mut self , item : & ast:: Item ) {
203
+ match item. kind {
204
+ ast:: ItemKind :: Use ( ..) if item. span . is_dummy ( ) => return ,
205
+ _ => { }
206
+ }
207
+
208
+ self . item_span = item. span_with_attributes ( ) ;
209
+ visit:: walk_item ( self , item) ;
210
+ }
211
+
212
+ fn visit_use_tree ( & mut self , use_tree : & ast:: UseTree , id : ast:: NodeId , _nested : bool ) {
213
+ if id == self . root_node_id {
214
+ let mut unused_import = UnusedImport {
215
+ use_tree : use_tree. clone ( ) ,
216
+ use_tree_id : id,
217
+ item_span : self . item_span ,
218
+ unused : Default :: default ( ) ,
219
+ } ;
220
+ unused_import. unused . insert ( self . node_id ) ;
221
+ self . unused_import = Some ( unused_import) ;
222
+ }
223
+ visit:: walk_use_tree ( self , use_tree, id) ;
224
+ }
225
+ }
226
+
227
+ #[ derive( Debug ) ]
193
228
enum UnusedSpanResult {
194
229
Used ,
195
230
FlatUnused ( Span , Span ) ,
@@ -507,7 +542,36 @@ impl Resolver<'_, '_> {
507
542
}
508
543
509
544
for import in check_redundant_imports {
510
- self . check_for_redundant_imports ( import) ;
545
+ if let Some ( redundant_spans) = self . check_for_redundant_imports ( import)
546
+ && let ImportKind :: Single { source, id, .. } = import. kind
547
+ {
548
+ let mut visitor = ImportVisitor {
549
+ node_id : id,
550
+ root_node_id : import. root_id ,
551
+ unused_import : None ,
552
+ item_span : Span :: default ( ) ,
553
+ } ;
554
+ visit:: walk_crate ( & mut visitor, krate) ;
555
+ if let Some ( unused) = visitor. unused_import {
556
+ let remove_span =
557
+ match calc_unused_spans ( & unused, & unused. use_tree , unused. use_tree_id ) {
558
+ UnusedSpanResult :: FlatUnused ( _, remove) => remove,
559
+ UnusedSpanResult :: NestedFullUnused ( _, remove) => remove,
560
+ UnusedSpanResult :: NestedPartialUnused ( _, removes) => {
561
+ assert_eq ! ( removes. len( ) , 1 ) ;
562
+ removes[ 0 ]
563
+ }
564
+ _ => import. use_span ,
565
+ } ;
566
+ self . lint_buffer . buffer_lint_with_diagnostic (
567
+ UNUSED_IMPORTS ,
568
+ id,
569
+ import. span ,
570
+ format ! ( "the item `{source}` is imported redundantly" ) ,
571
+ BuiltinLintDiag :: RedundantImport ( redundant_spans, source, remove_span) ,
572
+ ) ;
573
+ }
574
+ }
511
575
}
512
576
}
513
577
}
0 commit comments