diff options
| author | bjorn3 <bjorn3@users.noreply.github.com> | 2021-05-29 15:23:57 +0200 |
|---|---|---|
| committer | bjorn3 <bjorn3@users.noreply.github.com> | 2021-06-04 13:20:04 +0200 |
| commit | d96446c53cbe19814ea1b3bfce58b474fb0c0b44 (patch) | |
| tree | ee7953c54b83f09adf55fc84f24cafdd81ca88a0 | |
| parent | 1870f9b05f42b36747a9acce8cbb0e3dc81a3c9c (diff) | |
| download | rust-d96446c53cbe19814ea1b3bfce58b474fb0c0b44.tar.gz rust-d96446c53cbe19814ea1b3bfce58b474fb0c0b44.zip | |
Use SyncOnceCell in get_codegen_backend
This reduces the amount of unsafe code in get_codegen_backend
| -rw-r--r-- | compiler/rustc_interface/src/util.rs | 20 |
1 files changed, 9 insertions, 11 deletions
diff --git a/compiler/rustc_interface/src/util.rs b/compiler/rustc_interface/src/util.rs index 12309284dcd..d1d0eee365d 100644 --- a/compiler/rustc_interface/src/util.rs +++ b/compiler/rustc_interface/src/util.rs @@ -32,7 +32,7 @@ use std::ops::DerefMut; use std::panic; use std::path::{Path, PathBuf}; use std::sync::atomic::{AtomicBool, Ordering}; -use std::sync::{Arc, Mutex, Once}; +use std::sync::{Arc, Mutex}; use std::thread; use tracing::info; @@ -251,29 +251,27 @@ pub fn get_codegen_backend( maybe_sysroot: &Option<PathBuf>, backend_name: Option<&str>, ) -> Box<dyn CodegenBackend> { - static INIT: Once = Once::new(); + static LOAD: SyncOnceCell<unsafe fn() -> Box<dyn CodegenBackend>> = SyncOnceCell::new(); - static mut LOAD: fn() -> Box<dyn CodegenBackend> = || unreachable!(); - - INIT.call_once(|| { + let load = LOAD.get_or_init(|| { #[cfg(feature = "llvm")] const DEFAULT_CODEGEN_BACKEND: &str = "llvm"; #[cfg(not(feature = "llvm"))] const DEFAULT_CODEGEN_BACKEND: &str = "cranelift"; - let backend = match backend_name.unwrap_or(DEFAULT_CODEGEN_BACKEND) { + match backend_name.unwrap_or(DEFAULT_CODEGEN_BACKEND) { filename if filename.contains('.') => load_backend_from_dylib(filename.as_ref()), #[cfg(feature = "llvm")] "llvm" => rustc_codegen_llvm::LlvmCodegenBackend::new, backend_name => get_codegen_sysroot(maybe_sysroot, backend_name), - }; - - unsafe { - LOAD = backend; } }); - unsafe { LOAD() } + + // SAFETY: In case of a builtin codegen backend this is safe. In case of an external codegen + // backend we hope that the backend links against the same rustc_driver version. If this is not + // the case, we get UB. + unsafe { load() } } // This is used for rustdoc, but it uses similar machinery to codegen backend |
