@@ -5,6 +5,7 @@ use crate::rmeta::{CrateDep, CrateMetadata, CrateNumMap, CrateRoot, MetadataBlob
5
5
6
6
use rustc_ast:: expand:: allocator:: { global_allocator_spans, AllocatorKind } ;
7
7
use rustc_ast:: { ast, attr} ;
8
+ use rustc_data_structures:: fx:: FxHashSet ;
8
9
use rustc_data_structures:: svh:: Svh ;
9
10
use rustc_data_structures:: sync:: Lrc ;
10
11
use rustc_errors:: struct_span_err;
@@ -18,6 +19,7 @@ use rustc_middle::middle::cstore::{
18
19
} ;
19
20
use rustc_middle:: ty:: TyCtxt ;
20
21
use rustc_session:: config:: { self , CrateType } ;
22
+ use rustc_session:: lint;
21
23
use rustc_session:: output:: validate_crate_name;
22
24
use rustc_session:: search_paths:: PathKind ;
23
25
use rustc_session:: { CrateDisambiguator , Session } ;
@@ -49,6 +51,7 @@ pub struct CrateLoader<'a> {
49
51
local_crate_name : Symbol ,
50
52
// Mutable output.
51
53
cstore : CStore ,
54
+ used_extern_options : FxHashSet < Symbol > ,
52
55
}
53
56
54
57
pub enum LoadedMacro {
@@ -205,6 +208,7 @@ impl<'a> CrateLoader<'a> {
205
208
allocator_kind : None ,
206
209
has_global_allocator : false ,
207
210
} ,
211
+ used_extern_options : Default :: default ( ) ,
208
212
}
209
213
}
210
214
@@ -445,6 +449,9 @@ impl<'a> CrateLoader<'a> {
445
449
dep_kind : DepKind ,
446
450
dep : Option < ( & ' b CratePaths , & ' b CrateDep ) > ,
447
451
) -> CrateNum {
452
+ if dep. is_none ( ) {
453
+ self . used_extern_options . insert ( name) ;
454
+ }
448
455
self . maybe_resolve_crate ( name, span, dep_kind, dep) . unwrap_or_else ( |err| err. report ( ) )
449
456
}
450
457
@@ -839,6 +846,26 @@ impl<'a> CrateLoader<'a> {
839
846
} ) ;
840
847
}
841
848
849
+ fn report_unused_deps ( & mut self , krate : & ast:: Crate ) {
850
+ // Make a point span rather than covering the whole file
851
+ let span = krate. span . shrink_to_lo ( ) ;
852
+ // Complain about anything left over
853
+ for ( name, _) in self . sess . opts . externs . iter ( ) {
854
+ if !self . used_extern_options . contains ( & Symbol :: intern ( name) ) {
855
+ self . sess . parse_sess . buffer_lint (
856
+ lint:: builtin:: UNUSED_CRATE_DEPENDENCIES ,
857
+ span,
858
+ ast:: CRATE_NODE_ID ,
859
+ & format ! (
860
+ "external crate `{}` unused in `{}`: remove the dependency or add `use {} as _;`" ,
861
+ name,
862
+ self . local_crate_name,
863
+ name) ,
864
+ ) ;
865
+ }
866
+ }
867
+ }
868
+
842
869
pub fn postprocess ( & mut self , krate : & ast:: Crate ) {
843
870
self . inject_profiler_runtime ( ) ;
844
871
self . inject_allocator_crate ( krate) ;
@@ -847,6 +874,8 @@ impl<'a> CrateLoader<'a> {
847
874
if log_enabled ! ( log:: Level :: Info ) {
848
875
dump_crates ( & self . cstore ) ;
849
876
}
877
+
878
+ self . report_unused_deps ( krate) ;
850
879
}
851
880
852
881
pub fn process_extern_crate (
0 commit comments