@@ -137,6 +137,81 @@ impl<'a, 'b, 'tcx> UnusedImportCheckVisitor<'a, 'b, 'tcx> {
137137            self . check_import_as_underscore ( item,  * id) ; 
138138        } 
139139    } 
140+ 
141+     fn  report_unused_extern_crate_items ( 
142+         & mut  self , 
143+         maybe_unused_extern_crates :  FxHashMap < ast:: NodeId ,  Span > , 
144+     )  { 
145+         let  tcx = self . r . tcx ( ) ; 
146+         for  extern_crate in  & self . extern_crate_items  { 
147+             let  warn_if_unused = !extern_crate. ident . name . as_str ( ) . starts_with ( '_' ) ; 
148+ 
149+             // If the crate is fully unused, we suggest removing it altogether. 
150+             // We do this in any edition. 
151+             if  warn_if_unused { 
152+                 if  let  Some ( & span)  = maybe_unused_extern_crates. get ( & extern_crate. id )  { 
153+                     self . r . lint_buffer . buffer_lint_with_diagnostic ( 
154+                         UNUSED_EXTERN_CRATES , 
155+                         extern_crate. id , 
156+                         span, 
157+                         "unused extern crate" , 
158+                         BuiltinLintDiag :: UnusedExternCrate  { 
159+                             removal_span :  extern_crate. span_with_attributes , 
160+                         } , 
161+                     ) ; 
162+                     continue ; 
163+                 } 
164+             } 
165+ 
166+             // If we are not in Rust 2018 edition, then we don't make any further 
167+             // suggestions. 
168+             if  !tcx. sess . at_least_rust_2018 ( )  { 
169+                 continue ; 
170+             } 
171+ 
172+             // If the extern crate has any attributes, they may have funky 
173+             // semantics we can't faithfully represent using `use` (most 
174+             // notably `#[macro_use]`). Ignore it. 
175+             if  extern_crate. has_attrs  { 
176+                 continue ; 
177+             } 
178+ 
179+             // If the extern crate is renamed, then we cannot suggest replacing it with a use as this 
180+             // would not insert the new name into the prelude, where other imports in the crate may be 
181+             // expecting it. 
182+             if  extern_crate. renames  { 
183+                 continue ; 
184+             } 
185+ 
186+             // If the extern crate isn't in the extern prelude, 
187+             // there is no way it can be written as a `use`. 
188+             if  !self 
189+                 . r 
190+                 . extern_prelude 
191+                 . get ( & extern_crate. ident ) 
192+                 . is_some_and ( |entry| !entry. introduced_by_item ) 
193+             { 
194+                 continue ; 
195+             } 
196+ 
197+             let  vis_span = extern_crate
198+                 . vis_span 
199+                 . find_ancestor_inside ( extern_crate. span ) 
200+                 . unwrap_or ( extern_crate. vis_span ) ; 
201+             let  ident_span = extern_crate
202+                 . ident 
203+                 . span 
204+                 . find_ancestor_inside ( extern_crate. span ) 
205+                 . unwrap_or ( extern_crate. ident . span ) ; 
206+             self . r . lint_buffer . buffer_lint_with_diagnostic ( 
207+                 UNUSED_EXTERN_CRATES , 
208+                 extern_crate. id , 
209+                 extern_crate. span , 
210+                 "`extern crate` is not idiomatic in the new edition" , 
211+                 BuiltinLintDiag :: ExternCrateNotIdiomatic  {  vis_span,  ident_span } , 
212+             ) ; 
213+         } 
214+     } 
140215} 
141216
142217impl < ' a ,  ' b ,  ' tcx >  Visitor < ' a >  for  UnusedImportCheckVisitor < ' a ,  ' b ,  ' tcx >  { 
@@ -335,6 +410,8 @@ impl Resolver<'_, '_> {
335410        } ; 
336411        visit:: walk_crate ( & mut  visitor,  krate) ; 
337412
413+         visitor. report_unused_extern_crate_items ( maybe_unused_extern_crates) ; 
414+ 
338415        for  unused in  visitor. unused_imports . values ( )  { 
339416            let  mut  fixes = Vec :: new ( ) ; 
340417            let  spans = match  calc_unused_spans ( unused,  & unused. use_tree ,  unused. use_tree_id )  { 
@@ -416,75 +493,6 @@ impl Resolver<'_, '_> {
416493            ) ; 
417494        } 
418495
419-         for  extern_crate in  visitor. extern_crate_items  { 
420-             let  warn_if_unused = !extern_crate. ident . name . as_str ( ) . starts_with ( '_' ) ; 
421- 
422-             // If the crate is fully unused, we suggest removing it altogether. 
423-             // We do this in any edition. 
424-             if  warn_if_unused { 
425-                 if  let  Some ( & span)  = maybe_unused_extern_crates. get ( & extern_crate. id )  { 
426-                     visitor. r . lint_buffer . buffer_lint_with_diagnostic ( 
427-                         UNUSED_EXTERN_CRATES , 
428-                         extern_crate. id , 
429-                         span, 
430-                         "unused extern crate" , 
431-                         BuiltinLintDiag :: UnusedExternCrate  { 
432-                             removal_span :  extern_crate. span_with_attributes , 
433-                         } , 
434-                     ) ; 
435-                     continue ; 
436-                 } 
437-             } 
438- 
439-             // If we are not in Rust 2018 edition, then we don't make any further 
440-             // suggestions. 
441-             if  !tcx. sess . at_least_rust_2018 ( )  { 
442-                 continue ; 
443-             } 
444- 
445-             // If the extern crate has any attributes, they may have funky 
446-             // semantics we can't faithfully represent using `use` (most 
447-             // notably `#[macro_use]`). Ignore it. 
448-             if  extern_crate. has_attrs  { 
449-                 continue ; 
450-             } 
451- 
452-             // If the extern crate is renamed, then we cannot suggest replacing it with a use as this 
453-             // would not insert the new name into the prelude, where other imports in the crate may be 
454-             // expecting it. 
455-             if  extern_crate. renames  { 
456-                 continue ; 
457-             } 
458- 
459-             // If the extern crate isn't in the extern prelude, 
460-             // there is no way it can be written as a `use`. 
461-             if  !visitor
462-                 . r 
463-                 . extern_prelude 
464-                 . get ( & extern_crate. ident ) 
465-                 . is_some_and ( |entry| !entry. introduced_by_item ) 
466-             { 
467-                 continue ; 
468-             } 
469- 
470-             let  vis_span = extern_crate
471-                 . vis_span 
472-                 . find_ancestor_inside ( extern_crate. span ) 
473-                 . unwrap_or ( extern_crate. vis_span ) ; 
474-             let  ident_span = extern_crate
475-                 . ident 
476-                 . span 
477-                 . find_ancestor_inside ( extern_crate. span ) 
478-                 . unwrap_or ( extern_crate. ident . span ) ; 
479-             visitor. r . lint_buffer . buffer_lint_with_diagnostic ( 
480-                 UNUSED_EXTERN_CRATES , 
481-                 extern_crate. id , 
482-                 extern_crate. span , 
483-                 "`extern crate` is not idiomatic in the new edition" , 
484-                 BuiltinLintDiag :: ExternCrateNotIdiomatic  {  vis_span,  ident_span } , 
485-             ) ; 
486-         } 
487- 
488496        let  unused_imports = visitor. unused_imports ; 
489497        let  mut  check_redundant_imports = FxIndexSet :: default ( ) ; 
490498        for  module in  self . arenas . local_modules ( ) . iter ( )  { 
0 commit comments