2121
2222use std:: cmp:: max;
2323use std:: collections:: BTreeMap ;
24+ use std:: error:: Error ;
2425use std:: ffi:: OsString ;
2526use std:: fmt:: Write as _;
2627use std:: fs:: { self , File } ;
27- use std:: io:: { self , IsTerminal , Read , Write } ;
28+ use std:: io:: { self , BufWriter , IsTerminal , Read , Write , stdout } ;
2829use std:: panic:: { self , PanicHookInfo , catch_unwind} ;
2930use std:: path:: PathBuf ;
3031use std:: process:: { self , Command , Stdio } ;
@@ -45,7 +46,7 @@ use rustc_errors::registry::Registry;
4546use rustc_errors:: {
4647 ColorConfig , DiagCtxt , ErrCode , ErrorGuaranteed , FatalError , PResult , markdown,
4748} ;
48- use rustc_feature:: find_gated_cfg;
49+ use rustc_feature:: { LangFeaturesStatus , find_gated_cfg} ;
4950use rustc_interface:: util:: { self , get_codegen_backend} ;
5051use rustc_interface:: { Linker , Queries , interface, passes} ;
5152use rustc_lint:: unerased_lint_store;
@@ -377,6 +378,11 @@ fn run_compiler(
377378 return early_exit( ) ;
378379 }
379380
381+ if sess. opts. unstable_opts. dump_features_status {
382+ dump_features_status( sess, codegen_backend) ;
383+ return early_exit( ) ;
384+ }
385+
380386 if !has_input {
381387 #[ allow( rustc:: diagnostic_outside_of_impl) ]
382388 sess. dcx( ) . fatal( "no input filename given" ) ; // this is fatal
@@ -1571,6 +1577,30 @@ fn report_ice(
15711577 }
15721578}
15731579
1580+ fn dump_features_status( sess: & Session , codegen_backend: & dyn CodegenBackend ) {
1581+ #[ derive( serde:: Serialize ) ]
1582+ struct FeaturesStatus {
1583+ lang_features_status: LangFeaturesStatus ,
1584+ lib_features_status: locator:: LibFeaturesStatus ,
1585+ }
1586+
1587+ let result: Result <( ) , Box <dyn Error >> = try {
1588+ let lang_features_status = rustc_feature:: lang_features_status( ) ;
1589+ let lib_features_status =
1590+ rustc_metadata:: lib_features_status( sess, & * codegen_backend. metadata_loader( ) ) ?;
1591+ let value = FeaturesStatus { lang_features_status, lib_features_status } ;
1592+ let writer = stdout( ) ;
1593+ let writer = BufWriter :: new( writer) ;
1594+ serde_json:: to_writer_pretty( writer, & value) ?;
1595+ } ;
1596+
1597+ // this happens before the global context and more importantly the diagnostic context is setup,
1598+ // so we can't report with the proper machinery
1599+ if let Err ( error) = result {
1600+ panic!( "cannot emit feature status json: {error}" )
1601+ }
1602+ }
1603+
15741604/// This allows tools to enable rust logging without having to magically match rustc's
15751605/// tracing crate version.
15761606pub fn init_rustc_env_logger( early_dcx: & EarlyDiagCtxt ) {
0 commit comments