Skip to content

Commit fec3235

Browse files
authored
Rollup merge of rust-lang#120702 - bvanjoi:fix-120444, r=notriddle
docs: also check the inline stmt during redundant link check Fixes rust-lang#120444 This issue was brought about by querying `root::webdavfs::A`, a key that doesn't exist in `doc_link_resolutions`. To avoid a panic, I've altered the gating mechanism to allow this lint pass to be skipped. I'm not certain if this is the best solution. An alternative approach might be to leverage other info from the name resolutions instead of `doc_link_resolutions`. After all, all we need is to get the resolution from a combination of `(module, name)`. However, I believe they would yield the same outcome, both skipping this lint.
2 parents 65aa9ea + 0a50dba commit fec3235

File tree

6 files changed

+111
-18
lines changed

6 files changed

+111
-18
lines changed

src/librustdoc/clean/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ pub(crate) fn clean_doc_module<'tcx>(doc: &DocModule<'tcx>, cx: &mut DocContext<
8282
// but there's already an item with the same namespace and same name. Rust gives
8383
// priority to the not-imported one, so we should, too.
8484
items.extend(doc.items.values().flat_map(|(item, renamed, import_id)| {
85-
// First, lower everything other than imports.
85+
// First, lower everything other than glob imports.
8686
if matches!(item.kind, hir::ItemKind::Use(_, hir::UseKind::Glob)) {
8787
return Vec::new();
8888
}

src/librustdoc/passes/lint/redundant_explicit_links.rs

+32-17
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use rustc_hir::def::{DefKind, DocLinkResMap, Namespace, Res};
77
use rustc_hir::HirId;
88
use rustc_lint_defs::Applicability;
99
use rustc_resolve::rustdoc::source_span_for_markdown_range;
10+
use rustc_span::def_id::DefId;
1011
use rustc_span::Symbol;
1112

1213
use crate::clean::utils::find_nearest_parent_module;
@@ -33,17 +34,22 @@ pub(crate) fn visit_item(cx: &DocContext<'_>, item: &Item) {
3334
return;
3435
}
3536

36-
if item.link_names(&cx.cache).is_empty() {
37-
// If there's no link names in this item,
38-
// then we skip resolution querying to
39-
// avoid from panicking.
40-
return;
37+
if let Some(item_id) = item.def_id() {
38+
check_redundant_explicit_link_for_did(cx, item, item_id, hir_id, &doc);
4139
}
40+
if let Some(item_id) = item.inline_stmt_id {
41+
check_redundant_explicit_link_for_did(cx, item, item_id, hir_id, &doc);
42+
}
43+
}
4244

43-
let Some(item_id) = item.def_id() else {
44-
return;
45-
};
46-
let Some(local_item_id) = item_id.as_local() else {
45+
fn check_redundant_explicit_link_for_did<'md>(
46+
cx: &DocContext<'_>,
47+
item: &Item,
48+
did: DefId,
49+
hir_id: HirId,
50+
doc: &'md str,
51+
) {
52+
let Some(local_item_id) = did.as_local() else {
4753
return;
4854
};
4955

@@ -53,19 +59,34 @@ pub(crate) fn visit_item(cx: &DocContext<'_>, item: &Item) {
5359
return;
5460
}
5561
let is_private = !cx.render_options.document_private
56-
&& !cx.cache.effective_visibilities.is_directly_public(cx.tcx, item_id);
62+
&& !cx.cache.effective_visibilities.is_directly_public(cx.tcx, did);
5763
if is_private {
5864
return;
5965
}
6066

61-
check_redundant_explicit_link(cx, item, hir_id, &doc);
67+
let module_id = match cx.tcx.def_kind(did) {
68+
DefKind::Mod if item.inner_docs(cx.tcx) => did,
69+
_ => find_nearest_parent_module(cx.tcx, did).unwrap(),
70+
};
71+
72+
let Some(resolutions) =
73+
cx.tcx.resolutions(()).doc_link_resolutions.get(&module_id.expect_local())
74+
else {
75+
// If there's no resolutions in this module,
76+
// then we skip resolution querying to
77+
// avoid from panicking.
78+
return;
79+
};
80+
81+
check_redundant_explicit_link(cx, item, hir_id, &doc, &resolutions);
6282
}
6383

6484
fn check_redundant_explicit_link<'md>(
6585
cx: &DocContext<'_>,
6686
item: &Item,
6787
hir_id: HirId,
6888
doc: &'md str,
89+
resolutions: &DocLinkResMap,
6990
) -> Option<()> {
7091
let mut broken_line_callback = |link: BrokenLink<'md>| Some((link.reference, "".into()));
7192
let mut offset_iter = Parser::new_with_broken_link_callback(
@@ -74,12 +95,6 @@ fn check_redundant_explicit_link<'md>(
7495
Some(&mut broken_line_callback),
7596
)
7697
.into_offset_iter();
77-
let item_id = item.def_id()?;
78-
let module_id = match cx.tcx.def_kind(item_id) {
79-
DefKind::Mod if item.inner_docs(cx.tcx) => item_id,
80-
_ => find_nearest_parent_module(cx.tcx, item_id).unwrap(),
81-
};
82-
let resolutions = cx.tcx.doc_link_resolutions(module_id);
8398

8499
while let Some((event, link_range)) = offset_iter.next() {
85100
match event {
+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// compile-flags: --document-private-items
2+
3+
#![deny(rustdoc::redundant_explicit_links)]
4+
5+
mod webdavfs {
6+
pub struct A;
7+
pub struct B;
8+
}
9+
10+
/// [`Vfs`][crate::Vfs]
11+
pub use webdavfs::A;
12+
//~^^ error: redundant explicit link target
13+
14+
/// [`Vfs`]
15+
pub use webdavfs::B;
16+
17+
pub struct Vfs;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
error: redundant explicit link target
2+
--> $DIR/issue-120444-1.rs:10:13
3+
|
4+
LL | /// [`Vfs`][crate::Vfs]
5+
| ----- ^^^^^^^^^^ explicit target is redundant
6+
| |
7+
| because label contains path that resolves to same destination
8+
|
9+
= note: when a link's destination is not specified,
10+
the label is used to resolve intra-doc links
11+
note: the lint level is defined here
12+
--> $DIR/issue-120444-1.rs:3:9
13+
|
14+
LL | #![deny(rustdoc::redundant_explicit_links)]
15+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
16+
help: remove explicit link target
17+
|
18+
LL | /// [`Vfs`]
19+
| ~~~~~~~
20+
21+
error: aborting due to 1 previous error
22+
+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// compile-flags: --document-private-items
2+
3+
#![deny(rustdoc::redundant_explicit_links)]
4+
5+
pub mod webdavfs {
6+
pub struct A;
7+
pub struct B;
8+
}
9+
10+
/// [`Vfs`][crate::Vfs]
11+
pub use webdavfs::A;
12+
//~^^ error: redundant explicit link target
13+
14+
/// [`Vfs`]
15+
pub use webdavfs::B;
16+
17+
pub struct Vfs;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
error: redundant explicit link target
2+
--> $DIR/issue-120444-2.rs:10:13
3+
|
4+
LL | /// [`Vfs`][crate::Vfs]
5+
| ----- ^^^^^^^^^^ explicit target is redundant
6+
| |
7+
| because label contains path that resolves to same destination
8+
|
9+
= note: when a link's destination is not specified,
10+
the label is used to resolve intra-doc links
11+
note: the lint level is defined here
12+
--> $DIR/issue-120444-2.rs:3:9
13+
|
14+
LL | #![deny(rustdoc::redundant_explicit_links)]
15+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
16+
help: remove explicit link target
17+
|
18+
LL | /// [`Vfs`]
19+
| ~~~~~~~
20+
21+
error: aborting due to 1 previous error
22+

0 commit comments

Comments
 (0)