Skip to content

Commit de6c639

Browse files
Rollup merge of rust-lang#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 rust-lang#144965
2 parents 48d5756 + 34b358d commit de6c639

File tree

3 files changed

+60
-2
lines changed

3 files changed

+60
-2
lines changed

src/librustdoc/clean/types.rs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -480,10 +480,28 @@ impl Item {
480480
}
481481
}
482482

483+
/// If the item has doc comments from a reexport, returns the item id of that reexport,
484+
/// otherwise returns returns the item id.
485+
///
486+
/// This is used as a key for caching intra-doc link resolution,
487+
/// to prevent two reexports of the same item from using the same cache.
488+
pub(crate) fn item_or_reexport_id(&self) -> ItemId {
489+
// added documentation on a reexport is always prepended.
490+
self.attrs
491+
.doc_strings
492+
.first()
493+
.map(|x| x.item_id)
494+
.flatten()
495+
.map(ItemId::from)
496+
.unwrap_or(self.item_id)
497+
}
498+
483499
pub(crate) fn links(&self, cx: &Context<'_>) -> Vec<RenderedLink> {
484500
use crate::html::format::{href, link_tooltip};
485501

486-
let Some(links) = cx.cache().intra_doc_links.get(&self.item_id) else { return vec![] };
502+
let Some(links) = cx.cache().intra_doc_links.get(&self.item_or_reexport_id()) else {
503+
return vec![];
504+
};
487505
links
488506
.iter()
489507
.filter_map(|ItemLink { link: s, link_text, page_id: id, fragment }| {

src/librustdoc/passes/collect_intra_doc_links.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1082,7 +1082,12 @@ impl LinkCollector<'_, '_> {
10821082
for md_link in preprocessed_markdown_links(&doc) {
10831083
let link = self.resolve_link(&doc, item, item_id, module_id, &md_link);
10841084
if let Some(link) = link {
1085-
self.cx.cache.intra_doc_links.entry(item.item_id).or_default().insert(link);
1085+
self.cx
1086+
.cache
1087+
.intra_doc_links
1088+
.entry(item.item_or_reexport_id())
1089+
.or_default()
1090+
.insert(link);
10861091
}
10871092
}
10881093
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// regression test for https://github.com/rust-lang/rust/issues/144965
2+
3+
#![crate_name = "foo"]
4+
#![no_std]
5+
6+
#[doc(hidden)]
7+
pub struct MyStruct;
8+
9+
macro_rules! my_macro {
10+
() => {
11+
pub fn my_function() {}
12+
13+
/// Incorrect: [`my_function()`].
14+
#[doc(inline)]
15+
pub use $crate::MyStruct;
16+
17+
/// Correct: [`my_function`].
18+
pub struct AnotherStruct;
19+
};
20+
}
21+
22+
23+
pub mod one {
24+
//@ has 'foo/one/index.html'
25+
//@ has - '//dl[@class="item-table"]/dd[1]/a[@href="fn.my_function.html"]/code' 'my_function'
26+
//@ has - '//dl[@class="item-table"]/dd[2]/a[@href="fn.my_function.html"]/code' 'my_function()'
27+
my_macro!();
28+
}
29+
30+
pub mod two {
31+
//@ has 'foo/two/index.html'
32+
//@ has - '//dl[@class="item-table"]/dd[1]/a[@href="fn.my_function.html"]/code' 'my_function'
33+
//@ has - '//dl[@class="item-table"]/dd[2]/a[@href="fn.my_function.html"]/code' 'my_function()'
34+
my_macro!();
35+
}

0 commit comments

Comments
 (0)