Skip to content

Commit e05d397

Browse files
committed
Support multiple crate versions in --extern-html-root-url
#76296
1 parent 321e2ce commit e05d397

File tree

3 files changed

+33
-6
lines changed

3 files changed

+33
-6
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: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,11 @@ 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+
Crate names in this flag refer to the names in the [extern prelude], and support crates renamed
399+
via the `--extern` `rustc` flag.
400+
401+
[extern prelude]: https://doc.rust-lang.org/reference/names/preludes.html#extern-prelude
402+
398403
## `-Z force-unstable-if-unmarked`
399404

400405
Using this flag looks like this:

src/librustdoc/formats/cache.rs

Lines changed: 20 additions & 6 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,31 @@ 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
162177
// FIXME: this part is specific to HTML so it'd be nice to remove it from the common code
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+
let extern_url =
184+
render_options.extern_html_root_urls.get(name.as_str()).map(|u| &**u);
185+
e.location(extern_url, extern_url_takes_precedence, dst, tcx)
186+
});
173187
cx.cache.external_paths.insert(e.def_id(), (vec![name], ItemType::Module));
174188
}
175189

0 commit comments

Comments
 (0)