diff options
| author | Guillaume Gomez <guillaume1.gomez@gmail.com> | 2025-08-06 21:29:31 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-08-06 21:29:31 +0200 |
| commit | de6c639228a8fdadfb2b7b0d4c7ef80848d3643d (patch) | |
| tree | 5fd7702104c3f34e0d2210b60228c2da5f906329 | |
| parent | 48d57564cfc0da0e5b67580fa49bb86a7bff0325 (diff) | |
| parent | 34b358d52aa6842e512dacbf97c7d3a9e18795e6 (diff) | |
| download | rust-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.rs | 20 | ||||
| -rw-r--r-- | src/librustdoc/passes/collect_intra_doc_links.rs | 7 | ||||
| -rw-r--r-- | tests/rustdoc/intra-doc/macro-caching-144965.rs | 35 |
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!(); +} |
