about summary refs log tree commit diff
path: root/compiler/rustc_metadata/src
diff options
context:
space:
mode:
authorThe Miri Conjob Bot <miri@cron.bot>2024-02-22 05:02:05 +0000
committerThe Miri Conjob Bot <miri@cron.bot>2024-02-22 05:02:05 +0000
commit76a596c48d1b8ed3805e623e003c73edaf00c5fc (patch)
treed455bd062e68808928fdbdd46ff10e38d5c4575e /compiler/rustc_metadata/src
parentf5ec4cb37561743efd869d61e457ae39938c1680 (diff)
parentc5f69bdd5173a948e0131f934fa7c4cbf5e0b55f (diff)
Merge from rustc
Diffstat (limited to 'compiler/rustc_metadata/src')
-rw-r--r--compiler/rustc_metadata/src/creader.rs68
-rw-r--r--compiler/rustc_metadata/src/errors.rs5
-rw-r--r--compiler/rustc_metadata/src/lib.rs2
-rw-r--r--compiler/rustc_metadata/src/locator.rs8
-rw-r--r--compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs10
5 files changed, 63 insertions, 30 deletions
diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs
index c18f0e7b7b9..f65fe1a29c7 100644
--- a/compiler/rustc_metadata/src/creader.rs
+++ b/compiler/rustc_metadata/src/creader.rs
@@ -692,20 +692,8 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
         path: &Path,
         stable_crate_id: StableCrateId,
     ) -> Result<&'static [ProcMacro], CrateError> {
-        // Make sure the path contains a / or the linker will search for it.
-        let path = try_canonicalize(path).unwrap();
-        let lib = load_dylib(&path, 5).map_err(|err| CrateError::DlOpen(err))?;
-
         let sym_name = self.sess.generate_proc_macro_decls_symbol(stable_crate_id);
-        let sym = unsafe { lib.get::<*const &[ProcMacro]>(sym_name.as_bytes()) }
-            .map_err(|err| CrateError::DlSym(err.to_string()))?;
-
-        // Intentionally leak the dynamic library. We can't ever unload it
-        // since the library can make things that will live arbitrarily long.
-        let sym = unsafe { sym.into_raw() };
-        std::mem::forget(lib);
-
-        Ok(unsafe { **sym })
+        Ok(unsafe { *load_symbol_from_dylib::<*const &[ProcMacro]>(path, &sym_name)? })
     }
 
     fn inject_panic_runtime(&mut self, krate: &ast::Crate) {
@@ -926,7 +914,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
         what: &str,
         needs_dep: &dyn Fn(&CrateMetadata) -> bool,
     ) {
-        // don't perform this validation if the session has errors, as one of
+        // Don't perform this validation if the session has errors, as one of
         // those errors may indicate a circular dependency which could cause
         // this to stack overflow.
         if self.dcx().has_errors().is_some() {
@@ -1070,16 +1058,6 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
     pub fn maybe_process_path_extern(&mut self, name: Symbol) -> Option<CrateNum> {
         self.maybe_resolve_crate(name, CrateDepKind::Explicit, None).ok()
     }
-
-    pub fn unload_unused_crates(&mut self) {
-        for opt_cdata in &mut self.cstore.metas {
-            if let Some(cdata) = opt_cdata
-                && !cdata.used()
-            {
-                *opt_cdata = None;
-            }
-        }
-    }
 }
 
 fn global_allocator_spans(krate: &ast::Crate) -> Vec<Span> {
@@ -1126,6 +1104,10 @@ fn alloc_error_handler_spans(krate: &ast::Crate) -> Vec<Span> {
     f.spans
 }
 
+fn format_dlopen_err(e: &(dyn std::error::Error + 'static)) -> String {
+    e.sources().map(|e| format!(": {e}")).collect()
+}
+
 // On Windows the compiler would sometimes intermittently fail to open the
 // proc-macro DLL with `Error::LoadLibraryExW`. It is suspected that something in the
 // system still holds a lock on the file, so we retry a few times before calling it
@@ -1164,9 +1146,43 @@ fn load_dylib(path: &Path, max_attempts: usize) -> Result<libloading::Library, S
 
     let last_error = last_error.unwrap();
     let message = if let Some(src) = last_error.source() {
-        format!("{last_error} ({src}) (retried {max_attempts} times)")
+        format!("{} ({src}) (retried {max_attempts} times)", format_dlopen_err(&last_error))
     } else {
-        format!("{last_error} (retried {max_attempts} times)")
+        format!("{} (retried {max_attempts} times)", format_dlopen_err(&last_error))
     };
     Err(message)
 }
+
+pub enum DylibError {
+    DlOpen(String, String),
+    DlSym(String, String),
+}
+
+impl From<DylibError> for CrateError {
+    fn from(err: DylibError) -> CrateError {
+        match err {
+            DylibError::DlOpen(path, err) => CrateError::DlOpen(path, err),
+            DylibError::DlSym(path, err) => CrateError::DlSym(path, err),
+        }
+    }
+}
+
+pub unsafe fn load_symbol_from_dylib<T: Copy>(
+    path: &Path,
+    sym_name: &str,
+) -> Result<T, DylibError> {
+    // Make sure the path contains a / or the linker will search for it.
+    let path = try_canonicalize(path).unwrap();
+    let lib =
+        load_dylib(&path, 5).map_err(|err| DylibError::DlOpen(path.display().to_string(), err))?;
+
+    let sym = unsafe { lib.get::<T>(sym_name.as_bytes()) }
+        .map_err(|err| DylibError::DlSym(path.display().to_string(), format_dlopen_err(&err)))?;
+
+    // Intentionally leak the dynamic library. We can't ever unload it
+    // since the library can make things that will live arbitrarily long.
+    let sym = unsafe { sym.into_raw() };
+    std::mem::forget(lib);
+
+    Ok(*sym)
+}
diff --git a/compiler/rustc_metadata/src/errors.rs b/compiler/rustc_metadata/src/errors.rs
index d17bf0cf708..9a05d9ac0de 100644
--- a/compiler/rustc_metadata/src/errors.rs
+++ b/compiler/rustc_metadata/src/errors.rs
@@ -505,6 +505,8 @@ impl<G: EmissionGuarantee> IntoDiagnostic<'_, G> for MultipleCandidates {
         diag.code(E0464);
         diag.span(self.span);
         for (i, candidate) in self.candidates.iter().enumerate() {
+            // FIXME: make this translatable
+            #[allow(rustc::untranslatable_diagnostic)]
             diag.note(format!("candidate #{}: {}", i + 1, candidate.display()));
         }
         diag
@@ -533,6 +535,7 @@ pub struct StableCrateIdCollision {
 pub struct DlError {
     #[primary_span]
     pub span: Span,
+    pub path: String,
     pub err: String,
 }
 
@@ -601,6 +604,8 @@ impl<G: EmissionGuarantee> IntoDiagnostic<'_, G> for InvalidMetadataFiles {
         diag.code(E0786);
         diag.span(self.span);
         for crate_rejection in self.crate_rejections {
+            // FIXME: make this translatable
+            #[allow(rustc::untranslatable_diagnostic)]
             diag.note(crate_rejection);
         }
         diag
diff --git a/compiler/rustc_metadata/src/lib.rs b/compiler/rustc_metadata/src/lib.rs
index 70ad8598957..f133a2f5f73 100644
--- a/compiler/rustc_metadata/src/lib.rs
+++ b/compiler/rustc_metadata/src/lib.rs
@@ -3,6 +3,7 @@
 #![feature(rustdoc_internals)]
 #![allow(internal_features)]
 #![feature(decl_macro)]
+#![feature(error_iter)]
 #![feature(extract_if)]
 #![feature(coroutines)]
 #![feature(generic_nonzero)]
@@ -39,6 +40,7 @@ pub mod errors;
 pub mod fs;
 pub mod locator;
 
+pub use creader::{load_symbol_from_dylib, DylibError};
 pub use fs::{emit_wrapper_file, METADATA_FILENAME};
 pub use native_libs::find_native_static_library;
 pub use rmeta::{encode_metadata, rendered_const, EncodedMetadata, METADATA_HEADER};
diff --git a/compiler/rustc_metadata/src/locator.rs b/compiler/rustc_metadata/src/locator.rs
index 1ab965e2876..15f56db6278 100644
--- a/compiler/rustc_metadata/src/locator.rs
+++ b/compiler/rustc_metadata/src/locator.rs
@@ -921,8 +921,8 @@ pub(crate) enum CrateError {
     MultipleCandidates(Symbol, CrateFlavor, Vec<PathBuf>),
     SymbolConflictsCurrent(Symbol),
     StableCrateIdCollision(Symbol, Symbol),
-    DlOpen(String),
-    DlSym(String),
+    DlOpen(String, String),
+    DlSym(String, String),
     LocatorCombined(Box<CombinedLocatorError>),
     NotFound(Symbol),
 }
@@ -967,8 +967,8 @@ impl CrateError {
             CrateError::StableCrateIdCollision(crate_name0, crate_name1) => {
                 dcx.emit_err(errors::StableCrateIdCollision { span, crate_name0, crate_name1 });
             }
-            CrateError::DlOpen(s) | CrateError::DlSym(s) => {
-                dcx.emit_err(errors::DlError { span, err: s });
+            CrateError::DlOpen(path, err) | CrateError::DlSym(path, err) => {
+                dcx.emit_err(errors::DlError { span, path, err });
             }
             CrateError::LocatorCombined(locator) => {
                 let crate_name = locator.crate_name;
diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
index 9df28799f4f..2f507b258fe 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
@@ -519,6 +519,16 @@ pub(in crate::rmeta) fn provide(providers: &mut Providers) {
             tcx.untracked().cstore.freeze();
             tcx.arena.alloc_from_iter(CStore::from_tcx(tcx).iter_crate_data().map(|(cnum, _)| cnum))
         },
+        used_crates: |tcx, ()| {
+            // The list of loaded crates is now frozen in query cache,
+            // so make sure cstore is not mutably accessed from here on.
+            tcx.untracked().cstore.freeze();
+            tcx.arena.alloc_from_iter(
+                CStore::from_tcx(tcx)
+                    .iter_crate_data()
+                    .filter_map(|(cnum, data)| data.used().then_some(cnum)),
+            )
+        },
         ..providers.queries
     };
     provide_extern(&mut providers.extern_queries);