Auto merge of #109876 - jsha:uniquify-intra-doc, r=notriddle
rustdoc: make intra-doc link pass non-quadratic for repeated links In the collect_intra_doc_links pass, links to a given item that occurred repeatedly were getting inserted into a `Vec<clean::ItemLink>` repeatedly. This led to n^2 behavior (where n = the number of pages generated), particularly for the intra-doc link on the `Into<U> for T where U: From<T>` blanket implementation, since that link appears on every single struct page. Fixes #109851
This commit is contained in:
commit
eb48e9771a
@ -452,10 +452,12 @@ pub(crate) fn collapsed_doc_value(&self) -> Option<String> {
|
|||||||
pub(crate) fn links(&self, cx: &Context<'_>) -> Vec<RenderedLink> {
|
pub(crate) fn links(&self, cx: &Context<'_>) -> Vec<RenderedLink> {
|
||||||
use crate::html::format::{href, link_tooltip};
|
use crate::html::format::{href, link_tooltip};
|
||||||
|
|
||||||
cx.cache()
|
let Some(links) = cx.cache()
|
||||||
.intra_doc_links
|
.intra_doc_links
|
||||||
.get(&self.item_id)
|
.get(&self.item_id) else {
|
||||||
.map_or(&[][..], |v| v.as_slice())
|
return vec![]
|
||||||
|
};
|
||||||
|
links
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|ItemLink { link: s, link_text, page_id: id, ref fragment }| {
|
.filter_map(|ItemLink { link: s, link_text, page_id: id, ref fragment }| {
|
||||||
debug!(?id);
|
debug!(?id);
|
||||||
@ -483,10 +485,12 @@ pub(crate) fn links(&self, cx: &Context<'_>) -> Vec<RenderedLink> {
|
|||||||
/// the link text, but does need to know which `[]`-bracketed names
|
/// the link text, but does need to know which `[]`-bracketed names
|
||||||
/// are actually links.
|
/// are actually links.
|
||||||
pub(crate) fn link_names(&self, cache: &Cache) -> Vec<RenderedLink> {
|
pub(crate) fn link_names(&self, cache: &Cache) -> Vec<RenderedLink> {
|
||||||
cache
|
let Some(links) = cache
|
||||||
.intra_doc_links
|
.intra_doc_links
|
||||||
.get(&self.item_id)
|
.get(&self.item_id) else {
|
||||||
.map_or(&[][..], |v| v.as_slice())
|
return vec![];
|
||||||
|
};
|
||||||
|
links
|
||||||
.iter()
|
.iter()
|
||||||
.map(|ItemLink { link: s, link_text, .. }| RenderedLink {
|
.map(|ItemLink { link: s, link_text, .. }| RenderedLink {
|
||||||
original_text: s.clone(),
|
original_text: s.clone(),
|
||||||
@ -1006,7 +1010,7 @@ pub(crate) fn collapse_doc_fragments(doc_strings: &[DocFragment]) -> String {
|
|||||||
/// A link that has not yet been rendered.
|
/// A link that has not yet been rendered.
|
||||||
///
|
///
|
||||||
/// This link will be turned into a rendered link by [`Item::links`].
|
/// This link will be turned into a rendered link by [`Item::links`].
|
||||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||||
pub(crate) struct ItemLink {
|
pub(crate) struct ItemLink {
|
||||||
/// The original link written in the markdown
|
/// The original link written in the markdown
|
||||||
pub(crate) link: Box<str>,
|
pub(crate) link: Box<str>,
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use std::mem;
|
use std::mem;
|
||||||
|
|
||||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet};
|
||||||
use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, DefIdSet};
|
use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, DefIdSet};
|
||||||
use rustc_middle::ty::{self, TyCtxt};
|
use rustc_middle::ty::{self, TyCtxt};
|
||||||
use rustc_span::Symbol;
|
use rustc_span::Symbol;
|
||||||
@ -118,7 +118,7 @@ pub(crate) struct Cache {
|
|||||||
/// All intra-doc links resolved so far.
|
/// All intra-doc links resolved so far.
|
||||||
///
|
///
|
||||||
/// Links are indexed by the DefId of the item they document.
|
/// Links are indexed by the DefId of the item they document.
|
||||||
pub(crate) intra_doc_links: FxHashMap<ItemId, Vec<clean::ItemLink>>,
|
pub(crate) intra_doc_links: FxHashMap<ItemId, FxIndexSet<clean::ItemLink>>,
|
||||||
/// Cfg that have been hidden via #![doc(cfg_hide(...))]
|
/// Cfg that have been hidden via #![doc(cfg_hide(...))]
|
||||||
pub(crate) hidden_cfg: FxHashSet<clean::cfg::Cfg>,
|
pub(crate) hidden_cfg: FxHashSet<clean::cfg::Cfg>,
|
||||||
}
|
}
|
||||||
|
@ -978,7 +978,7 @@ fn resolve_links(&mut self, item: &Item) {
|
|||||||
for md_link in preprocessed_markdown_links(&doc) {
|
for md_link in preprocessed_markdown_links(&doc) {
|
||||||
let link = self.resolve_link(item, item_id, module_id, &doc, &md_link);
|
let link = self.resolve_link(item, item_id, module_id, &doc, &md_link);
|
||||||
if let Some(link) = link {
|
if let Some(link) = link {
|
||||||
self.cx.cache.intra_doc_links.entry(item.item_id).or_default().push(link);
|
self.cx.cache.intra_doc_links.entry(item.item_id).or_default().insert(link);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user