about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorGuillaume Gomez <guillaume1.gomez@gmail.com>2025-08-06 21:29:31 +0200
committerGitHub <noreply@github.com>2025-08-06 21:29:31 +0200
commitde6c639228a8fdadfb2b7b0d4c7ef80848d3643d (patch)
tree5fd7702104c3f34e0d2210b60228c2da5f906329 /src
parent48d57564cfc0da0e5b67580fa49bb86a7bff0325 (diff)
parent34b358d52aa6842e512dacbf97c7d3a9e18795e6 (diff)
downloadrust-de6c639228a8fdadfb2b7b0d4c7ef80848d3643d.tar.gz
rust-de6c639228a8fdadfb2b7b0d4c7ef80848d3643d.zip
Rollup merge of #144970 - lolbinarycat:rustdoc-macro-wrong-link-144965, r=GuillaumeGomez
rustdoc: fix caching of intra-doc links on reexports

previously two reexports of the same item would share a set of intra-doc links, which would cause problems if they had two different links with the same text.  this was fixed by using the reexport defid as the key, if it is available.

fixes https://github.com/rust-lang/rust/issues/144965
Diffstat (limited to 'src')
-rw-r--r--src/librustdoc/clean/types.rs20
-rw-r--r--src/librustdoc/passes/collect_intra_doc_links.rs7
2 files changed, 25 insertions, 2 deletions
diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs
index 782311e593b..26b087feb16 100644
--- a/src/librustdoc/clean/types.rs
+++ b/src/librustdoc/clean/types.rs
@@ -480,10 +480,28 @@ impl Item {
         }
     }
 
+    /// If the item has doc comments from a reexport, returns the item id of that reexport,
+    /// otherwise returns returns the item id.
+    ///
+    /// This is used as a key for caching intra-doc link resolution,
+    /// to prevent two reexports of the same item from using the same cache.
+    pub(crate) fn item_or_reexport_id(&self) -> ItemId {
+        // added documentation on a reexport is always prepended.
+        self.attrs
+            .doc_strings
+            .first()
+            .map(|x| x.item_id)
+            .flatten()
+            .map(ItemId::from)
+            .unwrap_or(self.item_id)
+    }
+
     pub(crate) fn links(&self, cx: &Context<'_>) -> Vec<RenderedLink> {
         use crate::html::format::{href, link_tooltip};
 
-        let Some(links) = cx.cache().intra_doc_links.get(&self.item_id) else { return vec![] };
+        let Some(links) = cx.cache().intra_doc_links.get(&self.item_or_reexport_id()) else {
+            return vec![];
+        };
         links
             .iter()
             .filter_map(|ItemLink { link: s, link_text, page_id: id, fragment }| {
diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs
index c9fa3a4837f..bcb676cd1f1 100644
--- a/src/librustdoc/passes/collect_intra_doc_links.rs
+++ b/src/librustdoc/passes/collect_intra_doc_links.rs
@@ -1082,7 +1082,12 @@ impl LinkCollector<'_, '_> {
             for md_link in preprocessed_markdown_links(&doc) {
                 let link = self.resolve_link(&doc, item, item_id, module_id, &md_link);
                 if let Some(link) = link {
-                    self.cx.cache.intra_doc_links.entry(item.item_id).or_default().insert(link);
+                    self.cx
+                        .cache
+                        .intra_doc_links
+                        .entry(item.item_or_reexport_id())
+                        .or_default()
+                        .insert(link);
                 }
             }
         }