@@ -32,7 +32,7 @@ use std::ops::DerefMut;
32
32
use std:: panic;
33
33
use std:: path:: { Path , PathBuf } ;
34
34
use std:: sync:: atomic:: { AtomicBool , Ordering } ;
35
- use std:: sync:: { Arc , Mutex , Once } ;
35
+ use std:: sync:: { Arc , Mutex } ;
36
36
use std:: thread;
37
37
use tracing:: info;
38
38
@@ -251,29 +251,27 @@ pub fn get_codegen_backend(
251
251
maybe_sysroot : & Option < PathBuf > ,
252
252
backend_name : Option < & str > ,
253
253
) -> Box < dyn CodegenBackend > {
254
- static INIT : Once = Once :: new ( ) ;
254
+ static LOAD : SyncOnceCell < unsafe fn ( ) -> Box < dyn CodegenBackend > > = SyncOnceCell :: new ( ) ;
255
255
256
- static mut LOAD : fn ( ) -> Box < dyn CodegenBackend > = || unreachable ! ( ) ;
257
-
258
- INIT . call_once ( || {
256
+ let load = LOAD . get_or_init ( || {
259
257
#[ cfg( feature = "llvm" ) ]
260
258
const DEFAULT_CODEGEN_BACKEND : & str = "llvm" ;
261
259
262
260
#[ cfg( not( feature = "llvm" ) ) ]
263
261
const DEFAULT_CODEGEN_BACKEND : & str = "cranelift" ;
264
262
265
- let backend = match backend_name. unwrap_or ( DEFAULT_CODEGEN_BACKEND ) {
263
+ match backend_name. unwrap_or ( DEFAULT_CODEGEN_BACKEND ) {
266
264
filename if filename. contains ( '.' ) => load_backend_from_dylib ( filename. as_ref ( ) ) ,
267
265
#[ cfg( feature = "llvm" ) ]
268
266
"llvm" => rustc_codegen_llvm:: LlvmCodegenBackend :: new,
269
267
backend_name => get_codegen_sysroot ( maybe_sysroot, backend_name) ,
270
- } ;
271
-
272
- unsafe {
273
- LOAD = backend;
274
268
}
275
269
} ) ;
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 ( ) }
277
275
}
278
276
279
277
// This is used for rustdoc, but it uses similar machinery to codegen backend
0 commit comments