Skip to content

Commit dd1ba42

Browse files
Rollup merge of #154453 - chenyukang:yukang-fix-154383, r=notriddle
Fix ice in rustdoc of private reexport Fixes #154383 The root cause is rustdoc could still try to resolve links for source docs that resolver did not cache in `ResolveDocLinks::Exported` mode. The test case will not crash with `--document-private-items` option, which will use `ResolveDocLinks::All`. The fix makes rustdoc skip link resolution based on the source `DefId` of each doc fragment, so its behavior stays aligned with resolver's logic here: https://github.com/chenyukang/rust/blob/dc5cb1719eed6ac9275fe93d914d32141606b2ac/compiler/rustc_resolve/src/late.rs#L685
2 parents 9f3c8ba + dc5cb17 commit dd1ba42

2 files changed

Lines changed: 28 additions & 8 deletions

File tree

src/librustdoc/passes/collect_intra_doc_links.rs

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1067,17 +1067,27 @@ impl LinkCollector<'_, '_> {
10671067
#[instrument(level = "debug", skip_all)]
10681068
fn resolve_links(&mut self, item: &Item) {
10691069
let tcx = self.cx.tcx;
1070-
if !self.cx.document_private()
1071-
&& let Some(def_id) = item.item_id.as_def_id()
1072-
&& let Some(def_id) = def_id.as_local()
1073-
&& !tcx.effective_visibilities(()).is_exported(def_id)
1074-
&& !has_primitive_or_keyword_or_attribute_docs(&item.attrs.other_attrs)
1070+
let document_private = self.cx.document_private();
1071+
let effective_visibilities = tcx.effective_visibilities(());
1072+
let should_skip_link_resolution = |item_id: DefId| {
1073+
!document_private
1074+
&& item_id
1075+
.as_local()
1076+
.is_some_and(|local_def_id| !effective_visibilities.is_exported(local_def_id))
1077+
&& !has_primitive_or_keyword_or_attribute_docs(&item.attrs.other_attrs)
1078+
};
1079+
1080+
if let Some(def_id) = item.item_id.as_def_id()
1081+
&& should_skip_link_resolution(def_id)
10751082
{
10761083
// Skip link resolution for non-exported items.
10771084
return;
10781085
}
10791086

1080-
let mut insert_links = |item_id, doc: &str| {
1087+
let mut try_insert_links = |item_id, doc: &str| {
1088+
if should_skip_link_resolution(item_id) {
1089+
return;
1090+
}
10811091
let module_id = match tcx.def_kind(item_id) {
10821092
DefKind::Mod if item.inner_docs(tcx) => item_id,
10831093
_ => find_nearest_parent_module(tcx, item_id).unwrap(),
@@ -1108,7 +1118,7 @@ impl LinkCollector<'_, '_> {
11081118
// NOTE: if there are links that start in one crate and end in another, this will not resolve them.
11091119
// This is a degenerate case and it's not supported by rustdoc.
11101120
let item_id = item_id.unwrap_or_else(|| item.item_id.expect_def_id());
1111-
insert_links(item_id, &doc)
1121+
try_insert_links(item_id, &doc)
11121122
}
11131123

11141124
// Also resolve links in the note text of `#[deprecated]`.
@@ -1137,7 +1147,7 @@ impl LinkCollector<'_, '_> {
11371147
} else {
11381148
item.item_id.expect_def_id()
11391149
};
1140-
insert_links(item_id, note)
1150+
try_insert_links(item_id, note)
11411151
}
11421152
}
11431153

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
//@ check-pass
2+
3+
// Regression test for <https://github.com/rust-lang/rust/issues/154383>.
4+
// Rustdoc used to ICE on the doc link attached to a `pub use` inside a
5+
// private module.
6+
7+
mod inner {
8+
/// [std::vec::Vec]
9+
pub use std::vec::Vec as MyVec;
10+
}

0 commit comments

Comments
 (0)