11use std:: any:: Any ;
2+ use std:: cell:: RefCell ;
23use std:: path:: PathBuf ;
34use std:: str:: FromStr ;
45use std:: sync:: atomic:: AtomicBool ;
5- use std:: sync:: { Arc , Mutex } ;
6+ use std:: sync:: { Arc , Weak } ;
67use std:: { env, io} ;
78
89use rand:: { RngCore , rng} ;
910use rustc_data_structures:: base_n:: { CASE_INSENSITIVE , ToBaseN } ;
1011use rustc_data_structures:: flock;
1112use rustc_data_structures:: fx:: { FxHashMap , FxHashSet , FxIndexSet } ;
1213use rustc_data_structures:: profiling:: { SelfProfiler , SelfProfilerRef } ;
13- use rustc_data_structures:: sync:: { DynSend , DynSync , Lock , MappedReadGuard , ReadGuard , RwLock } ;
14+ use rustc_data_structures:: sync:: {
15+ DynSend , DynSync , Lock , MappedReadGuard , ReadGuard , RwLock , WorkerLocal ,
16+ } ;
1417use rustc_errors:: annotate_snippet_emitter_writer:: AnnotateSnippetEmitter ;
1518use rustc_errors:: codes:: * ;
1619use rustc_errors:: emitter:: { DynEmitter , HumanReadableErrorType , OutputTheme , stderr_destination} ;
@@ -159,7 +162,8 @@ pub struct Session {
159162 /// with its own implementations.
160163 pub replaced_intrinsics : FxHashSet < Symbol > ,
161164
162- pub used_features : Arc < Mutex < FxHashSet < Symbol > > > ,
165+ pub used_features : Lock < Option < Arc < WorkerLocal < RefCell < FxHashSet < Symbol > > > > > > ,
166+ used_features_weak : Weak < WorkerLocal < RefCell < FxHashSet < Symbol > > > > ,
163167}
164168
165169#[ derive( Clone , Copy ) ]
@@ -194,6 +198,27 @@ impl Session {
194198 self . miri_unleashed_features . lock ( ) . push ( ( span, feature_gate) ) ;
195199 }
196200
201+ pub fn used_features_weak ( & self ) -> Weak < WorkerLocal < RefCell < FxHashSet < Symbol > > > > {
202+ self . used_features_weak . clone ( )
203+ }
204+
205+ // Collect used features into a single set from all threads.
206+ #[ allow( rustc:: potential_query_instability) ]
207+ pub fn take_used_features ( & self ) -> FxHashSet < Symbol > {
208+ let used_features = self . used_features . lock ( ) . take ( ) . expect ( "used_features must be set" ) ;
209+
210+ let mut result = FxHashSet :: default ( ) ;
211+ for set in Arc :: try_unwrap ( used_features)
212+ . ok ( )
213+ . expect ( "used_features has outstanding strong references" )
214+ . into_inner ( )
215+ {
216+ result. extend ( set. take ( ) ) ;
217+ }
218+
219+ result
220+ }
221+
197222 pub fn local_crate_source_file ( & self ) -> Option < RealFileName > {
198223 Some (
199224 self . source_map ( )
@@ -1066,6 +1091,8 @@ pub fn build_session(
10661091
10671092 let timings = TimingSectionHandler :: new ( sopts. json_timings ) ;
10681093
1094+ let used_features = Arc :: new ( WorkerLocal :: new ( |_| RefCell :: new ( FxHashSet :: default ( ) ) ) ) ;
1095+ let used_features_weak = Arc :: downgrade ( & used_features) ;
10691096 let sess = Session {
10701097 target,
10711098 host,
@@ -1090,7 +1117,8 @@ pub fn build_session(
10901117 host_filesearch,
10911118 invocation_temp,
10921119 replaced_intrinsics : FxHashSet :: default ( ) , // filled by `run_compiler`
1093- used_features : Arc :: new ( Mutex :: new ( FxHashSet :: default ( ) ) ) ,
1120+ used_features : Lock :: new ( Some ( used_features) ) ,
1121+ used_features_weak,
10941122 } ;
10951123
10961124 validate_commandline_args_with_session_available ( & sess) ;
0 commit comments