Save names of used extern crates

Tracks association between `self.sess.opts.externs` (aliases in `--extern alias=rlib`) and resolved `CrateNum`

Intended to allow Rustdoc match the aliases in `--extern-html-root-url`

Force-injected extern crates aren't included, since they're meant for the linker only
This commit is contained in:
Kornel 2025-07-15 10:48:17 +01:00
parent 671e083391
commit 8a0f976047
No known key found for this signature in database
2 changed files with 20 additions and 0 deletions

View file

@ -12,6 +12,7 @@ use rustc_data_structures::fx::FxHashSet;
use rustc_data_structures::owned_slice::OwnedSlice;
use rustc_data_structures::svh::Svh;
use rustc_data_structures::sync::{self, FreezeReadGuard, FreezeWriteGuard};
use rustc_data_structures::unord::UnordMap;
use rustc_expand::base::SyntaxExtension;
use rustc_fs_util::try_canonicalize;
use rustc_hir as hir;
@ -69,6 +70,9 @@ pub struct CStore {
/// This crate has a `#[alloc_error_handler]` item.
has_alloc_error_handler: bool,
/// Names that were used to load the crates via `extern crate` or paths.
resolved_externs: UnordMap<Symbol, CrateNum>,
/// Unused externs of the crate
unused_externs: Vec<Symbol>,
@ -249,6 +253,14 @@ impl CStore {
self.metas[cnum] = Some(Box::new(data));
}
/// Save the name used to resolve the extern crate in the local crate
///
/// The name isn't always the crate's own name, because `sess.opts.externs` can assign it another name.
/// It's also not always the same as the `DefId`'s symbol due to renames `extern crate resolved_name as defid_name`.
pub(crate) fn set_resolved_extern_crate_name(&mut self, name: Symbol, extern_crate: CrateNum) {
self.resolved_externs.insert(name, extern_crate);
}
pub(crate) fn iter_crate_data(&self) -> impl Iterator<Item = (CrateNum, &CrateMetadata)> {
self.metas
.iter_enumerated()
@ -475,6 +487,7 @@ impl CStore {
alloc_error_handler_kind: None,
has_global_allocator: false,
has_alloc_error_handler: false,
resolved_externs: UnordMap::default(),
unused_externs: Vec::new(),
used_extern_options: Default::default(),
}
@ -1308,6 +1321,7 @@ impl CStore {
let path_len = definitions.def_path(def_id).data.len();
self.update_extern_crate(
cnum,
name,
ExternCrate {
src: ExternCrateSource::Extern(def_id.to_def_id()),
span: item.span,
@ -1332,6 +1346,7 @@ impl CStore {
self.update_extern_crate(
cnum,
name,
ExternCrate {
src: ExternCrateSource::Path,
span,

View file

@ -628,15 +628,20 @@ impl CStore {
}
/// Track how an extern crate has been loaded. Called after resolving an import in the local crate.
///
/// * the `name` is for [`Self::set_resolved_extern_crate_name`] saving `--extern name=`
/// * `extern_crate` is for diagnostics
pub(crate) fn update_extern_crate(
&mut self,
cnum: CrateNum,
name: Symbol,
extern_crate: ExternCrate,
) {
debug_assert_eq!(
extern_crate.dependency_of, LOCAL_CRATE,
"this function should not be called on transitive dependencies"
);
self.set_resolved_extern_crate_name(name, cnum);
self.update_transitive_extern_crate_diagnostics(cnum, extern_crate);
}