Skip to content

Commit dd1d39e

Browse files
committed
Support multiple crate versions in --extern-html-root-url
#76296
1 parent 8324f2b commit dd1d39e

File tree

3 files changed

+34
-7
lines changed

3 files changed

+34
-7
lines changed

compiler/rustc_metadata/src/creader.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,14 @@ impl CStore {
280280
self.resolved_externs.insert(name, extern_crate);
281281
}
282282

283+
/// Crate resolved and loaded via the given extern name
284+
/// (corresponds to names in `sess.opts.externs`)
285+
///
286+
/// May be `None` if the crate wasn't used
287+
pub fn resolved_extern_crate(&self, externs_name: Symbol) -> Option<CrateNum> {
288+
self.resolved_externs.get(&externs_name).copied()
289+
}
290+
283291
pub(crate) fn iter_crate_data(&self) -> impl Iterator<Item = (CrateNum, &CrateMetadata)> {
284292
self.metas
285293
.iter_enumerated()

src/doc/rustdoc/src/unstable-features.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,9 @@ flags to control that behavior. When the `--extern-html-root-url` flag is given
395395
one of your dependencies, rustdoc use that URL for those docs. Keep in mind that if those docs exist
396396
in the output directory, those local docs will still override this flag.
397397

398+
The crate names in this flag are first matched against the names given in the `--extern name=` flags,
399+
and fall back to using crates' own names otherwise (e.g. for transitive dependencies and sysroot crates).
400+
398401
## `-Z force-unstable-if-unmarked`
399402

400403
Using this flag looks like this:

src/librustdoc/formats/cache.rs

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use std::mem;
33
use rustc_attr_data_structures::StabilityLevel;
44
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet};
55
use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, DefIdSet};
6+
use rustc_metadata::creader::CStore;
67
use rustc_middle::ty::{self, TyCtxt};
78
use rustc_span::Symbol;
89
use tracing::debug;
@@ -158,18 +159,33 @@ impl Cache {
158159
assert!(cx.external_traits.is_empty());
159160
cx.cache.traits = mem::take(&mut krate.external_traits);
160161

162+
let render_options = &cx.render_options;
163+
let extern_url_takes_precedence = render_options.extern_html_root_takes_precedence;
164+
let dst = &render_options.output;
165+
166+
// Make `--extern-html-root-url` support the same names as `--extern` whenever possible
167+
let cstore = CStore::from_tcx(tcx);
168+
for (name, extern_url) in &render_options.extern_html_root_urls {
169+
if let Some(crate_num) = cstore.resolved_extern_crate(Symbol::intern(name)) {
170+
let e = ExternalCrate { crate_num };
171+
let location = e.location(Some(extern_url), extern_url_takes_precedence, dst, tcx);
172+
cx.cache.extern_locations.insert(e.crate_num, location);
173+
}
174+
}
175+
161176
// Cache where all our extern crates are located
162-
// FIXME: this part is specific to HTML so it'd be nice to remove it from the common code
177+
// This is also used in the JSON output.
163178
for &crate_num in tcx.crates(()) {
164179
let e = ExternalCrate { crate_num };
165180

166181
let name = e.name(tcx);
167-
let render_options = &cx.render_options;
168-
let extern_url = render_options.extern_html_root_urls.get(name.as_str()).map(|u| &**u);
169-
let extern_url_takes_precedence = render_options.extern_html_root_takes_precedence;
170-
let dst = &render_options.output;
171-
let location = e.location(extern_url, extern_url_takes_precedence, dst, tcx);
172-
cx.cache.extern_locations.insert(e.crate_num, location);
182+
cx.cache.extern_locations.entry(e.crate_num).or_insert_with(|| {
183+
// falls back to matching by crates' own names, because
184+
// transitive dependencies and injected crates may be loaded without `--extern`
185+
let extern_url =
186+
render_options.extern_html_root_urls.get(name.as_str()).map(|u| &**u);
187+
e.location(extern_url, extern_url_takes_precedence, dst, tcx)
188+
});
173189
cx.cache.external_paths.insert(e.def_id(), (vec![name], ItemType::Module));
174190
}
175191

0 commit comments

Comments
 (0)