@@ -32,7 +32,7 @@ use std::ops::DerefMut;
3232use std:: panic;
3333use std:: path:: { Path , PathBuf } ;
3434use std:: sync:: atomic:: { AtomicBool , Ordering } ;
35- use std:: sync:: { Arc , Mutex , Once } ;
35+ use std:: sync:: { Arc , Mutex } ;
3636use std:: thread;
3737use tracing:: info;
3838
@@ -251,29 +251,27 @@ pub fn get_codegen_backend(
251251 maybe_sysroot : & Option < PathBuf > ,
252252 backend_name : Option < & str > ,
253253) -> Box < dyn CodegenBackend > {
254- static INIT : Once = Once :: new ( ) ;
254+ static LOAD : SyncOnceCell < unsafe fn ( ) -> Box < dyn CodegenBackend > > = SyncOnceCell :: new ( ) ;
255255
256- static mut LOAD : fn ( ) -> Box < dyn CodegenBackend > = || unreachable ! ( ) ;
257-
258- INIT . call_once ( || {
256+ let load = LOAD . get_or_init ( || {
259257 #[ cfg( feature = "llvm" ) ]
260258 const DEFAULT_CODEGEN_BACKEND : & str = "llvm" ;
261259
262260 #[ cfg( not( feature = "llvm" ) ) ]
263261 const DEFAULT_CODEGEN_BACKEND : & str = "cranelift" ;
264262
265- let backend = match backend_name. unwrap_or ( DEFAULT_CODEGEN_BACKEND ) {
263+ match backend_name. unwrap_or ( DEFAULT_CODEGEN_BACKEND ) {
266264 filename if filename. contains ( '.' ) => load_backend_from_dylib ( filename. as_ref ( ) ) ,
267265 #[ cfg( feature = "llvm" ) ]
268266 "llvm" => rustc_codegen_llvm:: LlvmCodegenBackend :: new,
269267 backend_name => get_codegen_sysroot ( maybe_sysroot, backend_name) ,
270- } ;
271-
272- unsafe {
273- LOAD = backend;
274268 }
275269 } ) ;
276- unsafe { LOAD ( ) }
270+
271+ // SAFETY: In case of a builtin codegen backend this is safe. In case of an external codegen
272+ // backend we hope that the backend links against the same rustc_driver version. If this is not
273+ // the case, we get UB.
274+ unsafe { load ( ) }
277275}
278276
279277// This is used for rustdoc, but it uses similar machinery to codegen backend
0 commit comments