about summary refs log tree commit diff
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
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
-rw-r--r--src/librustdoc/clean/types.rs20
-rw-r--r--src/librustdoc/passes/collect_intra_doc_links.rs7
-rw-r--r--tests/rustdoc/intra-doc/macro-caching-144965.rs35
3 files changed, 60 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);
                 }
             }
         }
diff --git a/tests/rustdoc/intra-doc/macro-caching-144965.rs b/tests/rustdoc/intra-doc/macro-caching-144965.rs
new file mode 100644
index 00000000000..e14b465aeea
--- /dev/null
+++ b/tests/rustdoc/intra-doc/macro-caching-144965.rs
@@ -0,0 +1,35 @@
+// regression test for https://github.com/rust-lang/rust/issues/144965
+
+#![crate_name = "foo"]
+#![no_std]
+
+#[doc(hidden)]
+pub struct MyStruct;
+
+macro_rules! my_macro {
+    () => {
+        pub fn my_function() {}
+
+        /// Incorrect: [`my_function()`].
+        #[doc(inline)]
+        pub use $crate::MyStruct;
+
+        /// Correct: [`my_function`].
+        pub struct AnotherStruct;
+    };
+}
+
+
+pub mod one {
+    //@ has 'foo/one/index.html'
+    //@ has - '//dl[@class="item-table"]/dd[1]/a[@href="fn.my_function.html"]/code' 'my_function'
+    //@ has - '//dl[@class="item-table"]/dd[2]/a[@href="fn.my_function.html"]/code' 'my_function()'
+    my_macro!();
+}
+
+pub mod two {
+    //@ has 'foo/two/index.html'
+    //@ has - '//dl[@class="item-table"]/dd[1]/a[@href="fn.my_function.html"]/code' 'my_function'
+    //@ has - '//dl[@class="item-table"]/dd[2]/a[@href="fn.my_function.html"]/code' 'my_function()'
+    my_macro!();
+}