diff options
Diffstat (limited to 'compiler/rustc_metadata/src')
| -rw-r--r-- | compiler/rustc_metadata/src/creader.rs | 68 | ||||
| -rw-r--r-- | compiler/rustc_metadata/src/errors.rs | 5 | ||||
| -rw-r--r-- | compiler/rustc_metadata/src/lib.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_metadata/src/locator.rs | 8 | ||||
| -rw-r--r-- | compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs | 10 |
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); |
