@@ -46,6 +46,9 @@ pub struct CStore {
4646 /// This map is used to verify we get no hash conflicts between
4747 /// `StableCrateId` values.
4848 stable_crate_ids : FxHashMap < StableCrateId , CrateNum > ,
49+
50+ /// Unused externs of the crate
51+ unused_externs : Vec < Symbol > ,
4952}
5053
5154pub struct CrateLoader < ' a > {
@@ -190,6 +193,21 @@ impl CStore {
190193 crate fn has_global_allocator ( & self ) -> bool {
191194 self . has_global_allocator
192195 }
196+
197+ pub fn report_unused_deps ( & self , tcx : TyCtxt < ' _ > ) {
198+ let level = tcx
199+ . lint_level_at_node ( lint:: builtin:: UNUSED_CRATE_DEPENDENCIES , rustc_hir:: CRATE_HIR_ID )
200+ . 0 ;
201+ if level != lint:: Level :: Allow && tcx. sess . opts . json_unused_externs {
202+ let unused_externs =
203+ self . unused_externs . iter ( ) . map ( |ident| ident. to_ident_string ( ) ) . collect :: < Vec < _ > > ( ) ;
204+ let unused_externs = unused_externs. iter ( ) . map ( String :: as_str) . collect :: < Vec < & str > > ( ) ;
205+ tcx. sess
206+ . parse_sess
207+ . span_diagnostic
208+ . emit_unused_externs ( level. as_str ( ) , & unused_externs) ;
209+ }
210+ }
193211}
194212
195213impl < ' a > CrateLoader < ' a > {
@@ -217,6 +235,7 @@ impl<'a> CrateLoader<'a> {
217235 allocator_kind : None ,
218236 has_global_allocator : false ,
219237 stable_crate_ids,
238+ unused_externs : Vec :: new ( ) ,
220239 } ,
221240 used_extern_options : Default :: default ( ) ,
222241 }
@@ -893,18 +912,23 @@ impl<'a> CrateLoader<'a> {
893912 fn report_unused_deps ( & mut self , krate : & ast:: Crate ) {
894913 // Make a point span rather than covering the whole file
895914 let span = krate. span . shrink_to_lo ( ) ;
896- let mut unused_externs = Vec :: new ( ) ;
897915 // Complain about anything left over
898916 for ( name, entry) in self . sess . opts . externs . iter ( ) {
899917 if let ExternLocation :: FoundInLibrarySearchDirectories = entry. location {
900918 // Don't worry about pathless `--extern foo` sysroot references
901919 continue ;
902920 }
903- if self . used_extern_options . contains ( & Symbol :: intern ( name) ) {
921+ let name_interned = Symbol :: intern ( name) ;
922+ if self . used_extern_options . contains ( & name_interned) {
904923 continue ;
905924 }
906925
907926 // Got a real unused --extern
927+ if self . sess . opts . json_unused_externs {
928+ self . cstore . unused_externs . push ( name_interned) ;
929+ continue ;
930+ }
931+
908932 let diag = match self . sess . opts . extern_dep_specs . get ( name) {
909933 Some ( loc) => BuiltinLintDiagnostics :: ExternDepSpec ( name. clone ( ) , loc. into ( ) ) ,
910934 None => {
@@ -918,7 +942,6 @@ impl<'a> CrateLoader<'a> {
918942 )
919943 }
920944 } ;
921- unused_externs. push ( name as & str ) ;
922945 self . sess . parse_sess . buffer_lint_with_diagnostic (
923946 lint:: builtin:: UNUSED_CRATE_DEPENDENCIES ,
924947 span,
@@ -931,19 +954,16 @@ impl<'a> CrateLoader<'a> {
931954 diag,
932955 ) ;
933956 }
934- if self . sess . opts . json_unused_externs {
935- self . sess . parse_sess . span_diagnostic . emit_unused_externs ( & unused_externs) ;
936- }
937957 }
938958
939959 pub fn postprocess ( & mut self , krate : & ast:: Crate ) {
940960 self . inject_profiler_runtime ( krate) ;
941961 self . inject_allocator_crate ( krate) ;
942962 self . inject_panic_runtime ( krate) ;
943963
944- info ! ( "{:?}" , CrateDump ( & self . cstore) ) ;
945-
946964 self . report_unused_deps ( krate) ;
965+
966+ info ! ( "{:?}" , CrateDump ( & self . cstore) ) ;
947967 }
948968
949969 pub fn process_extern_crate (
0 commit comments