Skip to content

Commit

Permalink
get rid of some false negatives in rustdoc::broken_intra_doc_links
Browse files Browse the repository at this point in the history
rustdoc will not try to do intra-doc linking if the "path"
of a link looks too much like a "real url".

however, only inline links ([text](url)) can actually contain
a url, other types of links (reference links, shortcut links)
contain a *reference* which is later resolved to an actual url.

the "path" in this case cannot be a url, and therefore it should
not be skipped due to looking like a url.

fixes rust-lang#54191
  • Loading branch information
lolbinarycat committed Nov 7, 2024
1 parent 7028d93 commit 8ae6586
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 4 deletions.
13 changes: 9 additions & 4 deletions src/librustdoc/passes/collect_intra_doc_links.rs
Original file line number Diff line number Diff line change
Expand Up @@ -930,13 +930,18 @@ fn preprocess_link(
ori_link: &MarkdownLink,
dox: &str,
) -> Option<Result<PreprocessingInfo, PreprocessingError>> {
// certain link kinds cannot have their path be urls,
// so they should not be ignored, no matter how much they look like urls.
// e.g. [https://example.com/] is not a link to example.com.
let can_be_url = ori_link.kind == LinkType::Inline || ori_link.kind == LinkType::Autolink;

// [] is mostly likely not supposed to be a link
if ori_link.link.is_empty() {
return None;
}

// Bail early for real links.
if ori_link.link.contains('/') {
if can_be_url && ori_link.link.contains('/') {
return None;
}

Expand All @@ -961,7 +966,7 @@ fn preprocess_link(
Ok(None) => (None, link, link),
Err((err_msg, relative_range)) => {
// Only report error if we would not have ignored this link. See issue #83859.
if !should_ignore_link_with_disambiguators(link) {
if can_be_url && !should_ignore_link_with_disambiguators(link) {
let disambiguator_range = match range_between_backticks(&ori_link.range, dox) {
MarkdownLinkRange::Destination(no_backticks_range) => {
MarkdownLinkRange::Destination(
Expand All @@ -978,7 +983,7 @@ fn preprocess_link(
}
};

if should_ignore_link(path_str) {
if can_be_url && should_ignore_link(path_str) {
return None;
}

Expand All @@ -995,7 +1000,7 @@ fn preprocess_link(
assert!(!path_str.contains(['<', '>'].as_slice()));

// The link is not an intra-doc link if it still contains spaces after stripping generics.
if path_str.contains(' ') {
if can_be_url && path_str.contains(' ') {
return None;
}

Expand Down
13 changes: 13 additions & 0 deletions tests/rustdoc-ui/bad-intra-doc.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#![no_std]
#![deny(rustdoc::broken_intra_doc_links)]

// regression test for https://github.com/rust-lang/rust/issues/54191

/// this is not a link to [`example.com`]
///
/// this link [`has spaces in it`].
///
/// attempted link to method: [`Foo.bar()`]
///
/// classic broken intra-doc link: [`Bar`]
pub struct Foo;
39 changes: 39 additions & 0 deletions tests/rustdoc-ui/bad-intra-doc.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
error: unresolved link to `example.com`
--> $DIR/bad-intra-doc.rs:6:29
|
LL | /// this is not a link to [`example.com`]
| ^^^^^^^^^^^ no item named `example.com` in scope
|
= help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
note: the lint level is defined here
--> $DIR/bad-intra-doc.rs:2:9
|
LL | #![deny(rustdoc::broken_intra_doc_links)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: unresolved link to `has spaces in it`
--> $DIR/bad-intra-doc.rs:8:17
|
LL | /// this link [`has spaces in it`].
| ^^^^^^^^^^^^^^^^ no item named `has spaces in it` in scope
|
= help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`

error: unresolved link to `Foo.bar`
--> $DIR/bad-intra-doc.rs:10:33
|
LL | /// attempted link to method: [`Foo.bar()`]
| ^^^^^^^^^ no item named `Foo.bar` in scope
|
= help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`

error: unresolved link to `Bar`
--> $DIR/bad-intra-doc.rs:12:38
|
LL | /// classic broken intra-doc link: [`Bar`]
| ^^^ no item named `Bar` in scope
|
= help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`

error: aborting due to 4 previous errors

0 comments on commit 8ae6586

Please sign in to comment.