From 5ae2d42a8c80807c7e3ae7e8aff165fb4d8e046f Mon Sep 17 00:00:00 2001 From: binarycat Date: Thu, 7 Nov 2024 15:33:45 -0600 Subject: [PATCH 1/7] get rid of some false negatives in rustdoc::broken_intra_doc_links 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. Co-authored-by: Michael Howell --- .../passes/collect_intra_doc_links.rs | 13 ++++++-- tests/rustdoc-ui/bad-intra-doc.rs | 13 ++++++++ tests/rustdoc-ui/bad-intra-doc.stderr | 31 +++++++++++++++++++ 3 files changed, 54 insertions(+), 3 deletions(-) create mode 100644 tests/rustdoc-ui/bad-intra-doc.rs create mode 100644 tests/rustdoc-ui/bad-intra-doc.stderr diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 5a9aa2a94c8b4..97f8a2be10b27 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -941,13 +941,20 @@ fn preprocess_link( ori_link: &MarkdownLink, dox: &str, ) -> Option> { + // 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::ShortcutUnknown + && ori_link.kind != LinkType::CollapsedUnknown + && ori_link.kind != LinkType::ReferenceUnknown; + // [] 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; } @@ -972,7 +979,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( @@ -989,7 +996,7 @@ fn preprocess_link( } }; - if should_ignore_link(path_str) { + if can_be_url && should_ignore_link(path_str) { return None; } diff --git a/tests/rustdoc-ui/bad-intra-doc.rs b/tests/rustdoc-ui/bad-intra-doc.rs new file mode 100644 index 0000000000000..7bc55756e670b --- /dev/null +++ b/tests/rustdoc-ui/bad-intra-doc.rs @@ -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`] //~ERROR unresolved link +/// +/// this link [`has spaces in it`]. +/// +/// attempted link to method: [`Foo.bar()`] //~ERROR unresolved link +/// +/// classic broken intra-doc link: [`Bar`] //~ERROR unresolved link +pub struct Foo; diff --git a/tests/rustdoc-ui/bad-intra-doc.stderr b/tests/rustdoc-ui/bad-intra-doc.stderr new file mode 100644 index 0000000000000..9533792b35b60 --- /dev/null +++ b/tests/rustdoc-ui/bad-intra-doc.stderr @@ -0,0 +1,31 @@ +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 `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 3 previous errors + From 87d7d80cec060690c9055fa93cb29dfe5eb79ce9 Mon Sep 17 00:00:00 2001 From: binarycat Date: Fri, 8 Nov 2024 13:59:56 -0600 Subject: [PATCH 2/7] adjust more unit tests to reflect more aggressive intra-doc linting --- .../disambiguator-endswith-named-suffix.rs | 30 ++--- ...disambiguator-endswith-named-suffix.stderr | 122 +++++++++++++++++- tests/rustdoc-ui/intra-doc/weird-syntax.rs | 2 +- .../rustdoc-ui/intra-doc/weird-syntax.stderr | 24 ++++ .../lints/redundant_explicit_links-utf8.rs | 14 +- .../redundant_explicit_links-utf8.stderr | 59 +++++++++ 6 files changed, 230 insertions(+), 21 deletions(-) create mode 100644 tests/rustdoc-ui/lints/redundant_explicit_links-utf8.stderr diff --git a/tests/rustdoc-ui/disambiguator-endswith-named-suffix.rs b/tests/rustdoc-ui/disambiguator-endswith-named-suffix.rs index 1174e16dd53fd..cb277d529ce77 100644 --- a/tests/rustdoc-ui/disambiguator-endswith-named-suffix.rs +++ b/tests/rustdoc-ui/disambiguator-endswith-named-suffix.rs @@ -2,67 +2,67 @@ //@ normalize-stderr: "nightly|beta|1\.[0-9][0-9]\.[0-9]" -> "$$CHANNEL" //! [struct@m!()] //~ WARN: unmatched disambiguator `struct` and suffix `!()` -//! [struct@m!{}] +//! [struct@m!{}] //~ WARN: unmatched disambiguator `struct` and suffix `!{}` //! [struct@m![]] //! [struct@f()] //~ WARN: unmatched disambiguator `struct` and suffix `()` //! [struct@m!] //~ WARN: unmatched disambiguator `struct` and suffix `!` //! //! [enum@m!()] //~ WARN: unmatched disambiguator `enum` and suffix `!()` -//! [enum@m!{}] +//! [enum@m!{}] //~ WARN: unmatched disambiguator `enum` and suffix `!{}` //! [enum@m![]] //! [enum@f()] //~ WARN: unmatched disambiguator `enum` and suffix `()` //! [enum@m!] //~ WARN: unmatched disambiguator `enum` and suffix `!` //! //! [trait@m!()] //~ WARN: unmatched disambiguator `trait` and suffix `!()` -//! [trait@m!{}] +//! [trait@m!{}] //~ WARN: unmatched disambiguator `trait` and suffix `!{}` //! [trait@m![]] //! [trait@f()] //~ WARN: unmatched disambiguator `trait` and suffix `()` //! [trait@m!] //~ WARN: unmatched disambiguator `trait` and suffix `!` //! //! [module@m!()] //~ WARN: unmatched disambiguator `module` and suffix `!()` -//! [module@m!{}] +//! [module@m!{}] //~ WARN: unmatched disambiguator `module` and suffix `!{}` //! [module@m![]] //! [module@f()] //~ WARN: unmatched disambiguator `module` and suffix `()` //! [module@m!] //~ WARN: unmatched disambiguator `module` and suffix `!` //! //! [mod@m!()] //~ WARN: unmatched disambiguator `mod` and suffix `!()` -//! [mod@m!{}] +//! [mod@m!{}] //~ WARN: unmatched disambiguator `mod` and suffix `!{}` //! [mod@m![]] //! [mod@f()] //~ WARN: unmatched disambiguator `mod` and suffix `()` //! [mod@m!] //~ WARN: unmatched disambiguator `mod` and suffix `!` //! //! [const@m!()] //~ WARN: unmatched disambiguator `const` and suffix `!()` -//! [const@m!{}] +//! [const@m!{}] //~ WARN: unmatched disambiguator `const` and suffix `!{}` //! [const@m![]] //! [const@f()] //~ WARN: incompatible link kind for `f` //! [const@m!] //~ WARN: unmatched disambiguator `const` and suffix `!` //! //! [constant@m!()] //~ WARN: unmatched disambiguator `constant` and suffix `!()` -//! [constant@m!{}] +//! [constant@m!{}] //~ WARN: unmatched disambiguator `constant` and suffix `!{}` //! [constant@m![]] //! [constant@f()] //~ WARN: incompatible link kind for `f` //! [constant@m!] //~ WARN: unmatched disambiguator `constant` and suffix `!` //! //! [static@m!()] //~ WARN: unmatched disambiguator `static` and suffix `!()` -//! [static@m!{}] +//! [static@m!{}] //~ WARN: unmatched disambiguator `static` and suffix `!{}` //! [static@m![]] //! [static@f()] //~ WARN: incompatible link kind for `f` //! [static@m!] //~ WARN: unmatched disambiguator `static` and suffix `!` //! //! [function@m!()] //~ WARN: unmatched disambiguator `function` and suffix `!()` -//! [function@m!{}] +//! [function@m!{}] //~ WARN: unmatched disambiguator `function` and suffix `!{}` //! [function@m![]] //! [function@f()] //! [function@m!] //~ WARN: unmatched disambiguator `function` and suffix `!` //! //! [fn@m!()] //~ WARN: unmatched disambiguator `fn` and suffix `!()` -//! [fn@m!{}] +//! [fn@m!{}] //~ WARN: unmatched disambiguator `fn` and suffix `!{}` //! [fn@m![]] //! [fn@f()] //! [fn@m!] //~ WARN: unmatched disambiguator `fn` and suffix `!` //! //! [method@m!()] //~ WARN: unmatched disambiguator `method` and suffix `!()` -//! [method@m!{}] +//! [method@m!{}] //~ WARN: unmatched disambiguator `method` and suffix `!{}` //! [method@m![]] //! [method@f()] //! [method@m!] //~ WARN: unmatched disambiguator `method` and suffix `!` @@ -74,13 +74,13 @@ //! [derive@m!] //~ WARN: incompatible link kind for `m` //! //! [type@m!()] //~ WARN: unmatched disambiguator `type` and suffix `!()` -//! [type@m!{}] +//! [type@m!{}] //~ WARN: unmatched disambiguator `type` and suffix `!{}` //! [type@m![]] //! [type@f()] //~ WARN: unmatched disambiguator `type` and suffix `()` //! [type@m!] //~ WARN: unmatched disambiguator `type` and suffix `!` //! //! [value@m!()] //~ WARN: unmatched disambiguator `value` and suffix `!()` -//! [value@m!{}] +//! [value@m!{}] //~ WARN: unmatched disambiguator `value` and suffix `!{}` //! [value@m![]] //! [value@f()] //! [value@m!] //~ WARN: unmatched disambiguator `value` and suffix `!` @@ -92,13 +92,13 @@ //! [macro@m!] //! //! [prim@m!()] //~ WARN: unmatched disambiguator `prim` and suffix `!()` -//! [prim@m!{}] +//! [prim@m!{}] //~ WARN: unmatched disambiguator `prim` and suffix `!{}` //! [prim@m![]] //! [prim@f()] //~ WARN: unmatched disambiguator `prim` and suffix `()` //! [prim@m!] //~ WARN: unmatched disambiguator `prim` and suffix `!` //! //! [primitive@m!()] //~ WARN: unmatched disambiguator `primitive` and suffix `!()` -//! [primitive@m!{}] +//! [primitive@m!{}] //~ WARN: unmatched disambiguator `primitive` and suffix `!{}` //! [primitive@m![]] //! [primitive@f()] //~ WARN: unmatched disambiguator `primitive` and suffix `()` //! [primitive@m!] //~ WARN: unmatched disambiguator `primitive` and suffix `!` diff --git a/tests/rustdoc-ui/disambiguator-endswith-named-suffix.stderr b/tests/rustdoc-ui/disambiguator-endswith-named-suffix.stderr index f4e40a4887383..1840338596880 100644 --- a/tests/rustdoc-ui/disambiguator-endswith-named-suffix.stderr +++ b/tests/rustdoc-ui/disambiguator-endswith-named-suffix.stderr @@ -7,6 +7,14 @@ LL | //! [struct@m!()] = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators = note: `#[warn(rustdoc::broken_intra_doc_links)]` on by default +warning: unmatched disambiguator `struct` and suffix `!{}` + --> $DIR/disambiguator-endswith-named-suffix.rs:5:6 + | +LL | //! [struct@m!{}] + | ^^^^^^ + | + = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + warning: unmatched disambiguator `struct` and suffix `()` --> $DIR/disambiguator-endswith-named-suffix.rs:7:6 | @@ -31,6 +39,14 @@ LL | //! [enum@m!()] | = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators +warning: unmatched disambiguator `enum` and suffix `!{}` + --> $DIR/disambiguator-endswith-named-suffix.rs:11:6 + | +LL | //! [enum@m!{}] + | ^^^^ + | + = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + warning: unmatched disambiguator `enum` and suffix `()` --> $DIR/disambiguator-endswith-named-suffix.rs:13:6 | @@ -55,6 +71,14 @@ LL | //! [trait@m!()] | = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators +warning: unmatched disambiguator `trait` and suffix `!{}` + --> $DIR/disambiguator-endswith-named-suffix.rs:17:6 + | +LL | //! [trait@m!{}] + | ^^^^^ + | + = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + warning: unmatched disambiguator `trait` and suffix `()` --> $DIR/disambiguator-endswith-named-suffix.rs:19:6 | @@ -79,6 +103,14 @@ LL | //! [module@m!()] | = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators +warning: unmatched disambiguator `module` and suffix `!{}` + --> $DIR/disambiguator-endswith-named-suffix.rs:23:6 + | +LL | //! [module@m!{}] + | ^^^^^^ + | + = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + warning: unmatched disambiguator `module` and suffix `()` --> $DIR/disambiguator-endswith-named-suffix.rs:25:6 | @@ -103,6 +135,14 @@ LL | //! [mod@m!()] | = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators +warning: unmatched disambiguator `mod` and suffix `!{}` + --> $DIR/disambiguator-endswith-named-suffix.rs:29:6 + | +LL | //! [mod@m!{}] + | ^^^ + | + = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + warning: unmatched disambiguator `mod` and suffix `()` --> $DIR/disambiguator-endswith-named-suffix.rs:31:6 | @@ -127,6 +167,14 @@ LL | //! [const@m!()] | = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators +warning: unmatched disambiguator `const` and suffix `!{}` + --> $DIR/disambiguator-endswith-named-suffix.rs:35:6 + | +LL | //! [const@m!{}] + | ^^^^^ + | + = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + warning: incompatible link kind for `f` --> $DIR/disambiguator-endswith-named-suffix.rs:37:6 | @@ -155,6 +203,14 @@ LL | //! [constant@m!()] | = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators +warning: unmatched disambiguator `constant` and suffix `!{}` + --> $DIR/disambiguator-endswith-named-suffix.rs:41:6 + | +LL | //! [constant@m!{}] + | ^^^^^^^^ + | + = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + warning: incompatible link kind for `f` --> $DIR/disambiguator-endswith-named-suffix.rs:43:6 | @@ -183,6 +239,14 @@ LL | //! [static@m!()] | = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators +warning: unmatched disambiguator `static` and suffix `!{}` + --> $DIR/disambiguator-endswith-named-suffix.rs:47:6 + | +LL | //! [static@m!{}] + | ^^^^^^ + | + = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + warning: incompatible link kind for `f` --> $DIR/disambiguator-endswith-named-suffix.rs:49:6 | @@ -211,6 +275,14 @@ LL | //! [function@m!()] | = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators +warning: unmatched disambiguator `function` and suffix `!{}` + --> $DIR/disambiguator-endswith-named-suffix.rs:53:6 + | +LL | //! [function@m!{}] + | ^^^^^^^^ + | + = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + warning: unmatched disambiguator `function` and suffix `!` --> $DIR/disambiguator-endswith-named-suffix.rs:56:6 | @@ -227,6 +299,14 @@ LL | //! [fn@m!()] | = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators +warning: unmatched disambiguator `fn` and suffix `!{}` + --> $DIR/disambiguator-endswith-named-suffix.rs:59:6 + | +LL | //! [fn@m!{}] + | ^^ + | + = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + warning: unmatched disambiguator `fn` and suffix `!` --> $DIR/disambiguator-endswith-named-suffix.rs:62:6 | @@ -243,6 +323,14 @@ LL | //! [method@m!()] | = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators +warning: unmatched disambiguator `method` and suffix `!{}` + --> $DIR/disambiguator-endswith-named-suffix.rs:65:6 + | +LL | //! [method@m!{}] + | ^^^^^^ + | + = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + warning: unmatched disambiguator `method` and suffix `!` --> $DIR/disambiguator-endswith-named-suffix.rs:68:6 | @@ -303,6 +391,14 @@ LL | //! [type@m!()] | = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators +warning: unmatched disambiguator `type` and suffix `!{}` + --> $DIR/disambiguator-endswith-named-suffix.rs:77:6 + | +LL | //! [type@m!{}] + | ^^^^ + | + = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + warning: unmatched disambiguator `type` and suffix `()` --> $DIR/disambiguator-endswith-named-suffix.rs:79:6 | @@ -327,6 +423,14 @@ LL | //! [value@m!()] | = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators +warning: unmatched disambiguator `value` and suffix `!{}` + --> $DIR/disambiguator-endswith-named-suffix.rs:83:6 + | +LL | //! [value@m!{}] + | ^^^^^ + | + = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + warning: unmatched disambiguator `value` and suffix `!` --> $DIR/disambiguator-endswith-named-suffix.rs:86:6 | @@ -351,6 +455,14 @@ LL | //! [prim@m!()] | = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators +warning: unmatched disambiguator `prim` and suffix `!{}` + --> $DIR/disambiguator-endswith-named-suffix.rs:95:6 + | +LL | //! [prim@m!{}] + | ^^^^ + | + = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + warning: unmatched disambiguator `prim` and suffix `()` --> $DIR/disambiguator-endswith-named-suffix.rs:97:6 | @@ -375,6 +487,14 @@ LL | //! [primitive@m!()] | = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators +warning: unmatched disambiguator `primitive` and suffix `!{}` + --> $DIR/disambiguator-endswith-named-suffix.rs:101:6 + | +LL | //! [primitive@m!{}] + | ^^^^^^^^^ + | + = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators + warning: unmatched disambiguator `primitive` and suffix `()` --> $DIR/disambiguator-endswith-named-suffix.rs:103:6 | @@ -391,5 +511,5 @@ LL | //! [primitive@m!] | = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators -warning: 46 warnings emitted +warning: 61 warnings emitted diff --git a/tests/rustdoc-ui/intra-doc/weird-syntax.rs b/tests/rustdoc-ui/intra-doc/weird-syntax.rs index d2a922b2b6247..1c5977b1bc33d 100644 --- a/tests/rustdoc-ui/intra-doc/weird-syntax.rs +++ b/tests/rustdoc-ui/intra-doc/weird-syntax.rs @@ -65,7 +65,7 @@ pub struct XLinkToCloneWithStartSpace; /// [x][struct@Clone ] //~ERROR link pub struct XLinkToCloneWithEndSpace; -/// [x][Clone\(\)] not URL-shaped enough +/// [x][Clone\(\)] //~ERROR link pub struct XLinkToCloneWithEscapedParens; /// [x][`Clone`] not URL-shaped enough diff --git a/tests/rustdoc-ui/intra-doc/weird-syntax.stderr b/tests/rustdoc-ui/intra-doc/weird-syntax.stderr index ad813f0f9b623..3a567e409eff7 100644 --- a/tests/rustdoc-ui/intra-doc/weird-syntax.stderr +++ b/tests/rustdoc-ui/intra-doc/weird-syntax.stderr @@ -123,6 +123,14 @@ LL - /// [x][struct@Clone ] LL + /// [x][trait@Clone ] | +error: unresolved link to `Clone\(\)` + --> $DIR/weird-syntax.rs:68:9 + | +LL | /// [x][Clone\(\)] + | ^^^^^^^^^ no item named `Clone\(\)` in scope + | + = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` + error: unresolved link to `Clone` --> $DIR/weird-syntax.rs:74:9 | @@ -299,5 +307,21 @@ LL | /// - [`SDL_PROP_WINDOW_CREATE_COCOA_WINDOW_POINTER`]: the | = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` +error: unresolved link to `Clone` + --> $DIR/weird-syntax.rs:132:9 + | +LL | /// The [cln][] link here will produce a plain text suggestion + | ^^^^^ this link resolves to the trait `Clone`, which is not a function + | + = help: to link to the trait, prefix with `trait@`: trait@Clone + +error: incompatible link kind for `Clone` + --> $DIR/weird-syntax.rs:137:9 + | +LL | /// The [cln][] link here will produce a plain text suggestion + | ^^^^^ this link resolved to a trait, which is not a struct + | + = help: to link to the trait, prefix with `trait@`: trait@Clone + error: aborting due to 27 previous errors diff --git a/tests/rustdoc-ui/lints/redundant_explicit_links-utf8.rs b/tests/rustdoc-ui/lints/redundant_explicit_links-utf8.rs index 4f4590d45fc88..81cd6c73d1c17 100644 --- a/tests/rustdoc-ui/lints/redundant_explicit_links-utf8.rs +++ b/tests/rustdoc-ui/lints/redundant_explicit_links-utf8.rs @@ -1,18 +1,24 @@ //@ check-pass -/// [`…foo`] [`…bar`] [`Err`] +/// [`…foo`] //~ WARN: unresolved link +/// [`…bar`] //~ WARN: unresolved link +/// [`Err`] pub struct Broken {} -/// [`…`] [`…`] [`Err`] +/// [`…`] //~ WARN: unresolved link +/// [`…`] //~ WARN: unresolved link +/// [`Err`] pub struct Broken2 {} -/// [`…`][…] [`…`][…] [`Err`] +/// [`…`][…] //~ WARN: unresolved link +/// [`…`][…] //~ WARN: unresolved link +/// [`Err`] pub struct Broken3 {} /// […………………………][Broken3] pub struct Broken4 {} -/// [Broken3][…………………………] +/// [Broken3][…………………………] //~ WARN: unresolved link pub struct Broken5 {} pub struct Err; diff --git a/tests/rustdoc-ui/lints/redundant_explicit_links-utf8.stderr b/tests/rustdoc-ui/lints/redundant_explicit_links-utf8.stderr new file mode 100644 index 0000000000000..0a5ff68b90814 --- /dev/null +++ b/tests/rustdoc-ui/lints/redundant_explicit_links-utf8.stderr @@ -0,0 +1,59 @@ +warning: unresolved link to `…foo` + --> $DIR/redundant_explicit_links-utf8.rs:3:7 + | +LL | /// [`…foo`] + | ^^^^ no item named `…foo` in scope + | + = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` + = note: `#[warn(rustdoc::broken_intra_doc_links)]` on by default + +warning: unresolved link to `…bar` + --> $DIR/redundant_explicit_links-utf8.rs:4:7 + | +LL | /// [`…bar`] + | ^^^^ no item named `…bar` in scope + | + = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` + +warning: unresolved link to `…` + --> $DIR/redundant_explicit_links-utf8.rs:8:7 + | +LL | /// [`…`] + | ^ no item named `…` in scope + | + = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` + +warning: unresolved link to `…` + --> $DIR/redundant_explicit_links-utf8.rs:9:7 + | +LL | /// [`…`] + | ^ no item named `…` in scope + | + = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` + +warning: unresolved link to `…` + --> $DIR/redundant_explicit_links-utf8.rs:13:11 + | +LL | /// [`…`][…] + | ^ no item named `…` in scope + | + = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` + +warning: unresolved link to `…` + --> $DIR/redundant_explicit_links-utf8.rs:14:11 + | +LL | /// [`…`][…] + | ^ no item named `…` in scope + | + = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` + +warning: unresolved link to `…………………………` + --> $DIR/redundant_explicit_links-utf8.rs:21:15 + | +LL | /// [Broken3][…………………………] + | ^^^^^^^^^^ no item named `…………………………` in scope + | + = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` + +warning: 7 warnings emitted + From a7da4b829d328f129e342917908b70c5f4b98abc Mon Sep 17 00:00:00 2001 From: binarycat Date: Fri, 18 Apr 2025 15:32:56 -0500 Subject: [PATCH 3/7] rustdoc::broken_intra_doc_links: no backticks = use old behavior this is in an effort to reduce the amount of code churn caused by this lint triggering on text that was never meant to be a link. a more principled hierustic for ignoring lints is not possible without extensive changes, due to the lint emitting code being so far away from the link collecting code, and the fact that only the link collecting code has access to details about how the link appears in the unnormalized markdown. --- src/librustdoc/passes/collect_intra_doc_links.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 97f8a2be10b27..08f0d4015fcaf 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -996,7 +996,9 @@ fn preprocess_link( } }; - if can_be_url && should_ignore_link(path_str) { + // If there's no backticks, be lenient revert to old behavior. + // This is to prevent churn by linting on stuff that isn't meant to be a link. + if (can_be_url || !ori_link.link.contains('`')) && should_ignore_link(path_str) { return None; } From 041348110e2e526a80efd5adfc2909c716cbb37f Mon Sep 17 00:00:00 2001 From: binarycat Date: Fri, 18 Apr 2025 17:15:11 -0500 Subject: [PATCH 4/7] rustdoc: update tests to match new lint behavior --- tests/rustdoc-ui/bad-intra-doc.rs | 2 ++ tests/rustdoc-ui/intra-doc/weird-syntax.rs | 2 +- .../rustdoc-ui/intra-doc/weird-syntax.stderr | 24 ------------------- 3 files changed, 3 insertions(+), 25 deletions(-) diff --git a/tests/rustdoc-ui/bad-intra-doc.rs b/tests/rustdoc-ui/bad-intra-doc.rs index 7bc55756e670b..c24a848d8985c 100644 --- a/tests/rustdoc-ui/bad-intra-doc.rs +++ b/tests/rustdoc-ui/bad-intra-doc.rs @@ -10,4 +10,6 @@ /// attempted link to method: [`Foo.bar()`] //~ERROR unresolved link /// /// classic broken intra-doc link: [`Bar`] //~ERROR unresolved link +/// +/// no backticks, so we let this one slide: [Foo.bar()] pub struct Foo; diff --git a/tests/rustdoc-ui/intra-doc/weird-syntax.rs b/tests/rustdoc-ui/intra-doc/weird-syntax.rs index 1c5977b1bc33d..9f18f67fc44ab 100644 --- a/tests/rustdoc-ui/intra-doc/weird-syntax.rs +++ b/tests/rustdoc-ui/intra-doc/weird-syntax.rs @@ -65,7 +65,7 @@ pub struct XLinkToCloneWithStartSpace; /// [x][struct@Clone ] //~ERROR link pub struct XLinkToCloneWithEndSpace; -/// [x][Clone\(\)] //~ERROR link +/// [x][Clone\(\)] pub struct XLinkToCloneWithEscapedParens; /// [x][`Clone`] not URL-shaped enough diff --git a/tests/rustdoc-ui/intra-doc/weird-syntax.stderr b/tests/rustdoc-ui/intra-doc/weird-syntax.stderr index 3a567e409eff7..ad813f0f9b623 100644 --- a/tests/rustdoc-ui/intra-doc/weird-syntax.stderr +++ b/tests/rustdoc-ui/intra-doc/weird-syntax.stderr @@ -123,14 +123,6 @@ LL - /// [x][struct@Clone ] LL + /// [x][trait@Clone ] | -error: unresolved link to `Clone\(\)` - --> $DIR/weird-syntax.rs:68:9 - | -LL | /// [x][Clone\(\)] - | ^^^^^^^^^ no item named `Clone\(\)` in scope - | - = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` - error: unresolved link to `Clone` --> $DIR/weird-syntax.rs:74:9 | @@ -307,21 +299,5 @@ LL | /// - [`SDL_PROP_WINDOW_CREATE_COCOA_WINDOW_POINTER`]: the | = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` -error: unresolved link to `Clone` - --> $DIR/weird-syntax.rs:132:9 - | -LL | /// The [cln][] link here will produce a plain text suggestion - | ^^^^^ this link resolves to the trait `Clone`, which is not a function - | - = help: to link to the trait, prefix with `trait@`: trait@Clone - -error: incompatible link kind for `Clone` - --> $DIR/weird-syntax.rs:137:9 - | -LL | /// The [cln][] link here will produce a plain text suggestion - | ^^^^^ this link resolved to a trait, which is not a struct - | - = help: to link to the trait, prefix with `trait@`: trait@Clone - error: aborting due to 27 previous errors From 6a7d4882a207890c75ca09ce19810d90ac9cfde6 Mon Sep 17 00:00:00 2001 From: binarycat Date: Fri, 18 Apr 2025 20:23:05 -0500 Subject: [PATCH 5/7] rustdoc::broken_intra_doc_links: only be lenient with shortcut links MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit collapsed links and reference links have a pretty particular syntax, it seems unlikely they would show up on accident. Co-authored-by: León Orell Valerian Liehr --- .../passes/collect_intra_doc_links.rs | 27 +++++++++++++++---- tests/rustdoc-ui/intra-doc/weird-syntax.rs | 2 +- .../rustdoc-ui/intra-doc/weird-syntax.stderr | 10 ++++++- 3 files changed, 32 insertions(+), 7 deletions(-) diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 08f0d4015fcaf..c9fa3a4837f29 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -944,9 +944,10 @@ fn preprocess_link( // 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::ShortcutUnknown - && ori_link.kind != LinkType::CollapsedUnknown - && ori_link.kind != LinkType::ReferenceUnknown; + let can_be_url = !matches!( + ori_link.kind, + LinkType::ShortcutUnknown | LinkType::CollapsedUnknown | LinkType::ReferenceUnknown + ); // [] is mostly likely not supposed to be a link if ori_link.link.is_empty() { @@ -996,9 +997,25 @@ fn preprocess_link( } }; - // If there's no backticks, be lenient revert to old behavior. + // If there's no backticks, be lenient and revert to the old behavior. // This is to prevent churn by linting on stuff that isn't meant to be a link. - if (can_be_url || !ori_link.link.contains('`')) && should_ignore_link(path_str) { + // only shortcut links have simple enough syntax that they + // are likely to be written accidentally, collapsed and reference links + // need 4 metachars, and reference links will not usually use + // backticks in the reference name. + // therefore, only shortcut syntax gets the lenient behavior. + // + // here's a truth table for how link kinds that cannot be urls are handled: + // + // |-------------------------------------------------------| + // | | is shortcut link | not shortcut link | + // |--------------|--------------------|-------------------| + // | has backtick | never ignore | never ignore | + // | no backtick | ignore if url-like | never ignore | + // |-------------------------------------------------------| + let ignore_urllike = + can_be_url || (ori_link.kind == LinkType::ShortcutUnknown && !ori_link.link.contains('`')); + if ignore_urllike && should_ignore_link(path_str) { return None; } diff --git a/tests/rustdoc-ui/intra-doc/weird-syntax.rs b/tests/rustdoc-ui/intra-doc/weird-syntax.rs index 9f18f67fc44ab..1c5977b1bc33d 100644 --- a/tests/rustdoc-ui/intra-doc/weird-syntax.rs +++ b/tests/rustdoc-ui/intra-doc/weird-syntax.rs @@ -65,7 +65,7 @@ pub struct XLinkToCloneWithStartSpace; /// [x][struct@Clone ] //~ERROR link pub struct XLinkToCloneWithEndSpace; -/// [x][Clone\(\)] +/// [x][Clone\(\)] //~ERROR link pub struct XLinkToCloneWithEscapedParens; /// [x][`Clone`] not URL-shaped enough diff --git a/tests/rustdoc-ui/intra-doc/weird-syntax.stderr b/tests/rustdoc-ui/intra-doc/weird-syntax.stderr index ad813f0f9b623..7f2fc1fe62562 100644 --- a/tests/rustdoc-ui/intra-doc/weird-syntax.stderr +++ b/tests/rustdoc-ui/intra-doc/weird-syntax.stderr @@ -123,6 +123,14 @@ LL - /// [x][struct@Clone ] LL + /// [x][trait@Clone ] | +error: unresolved link to `Clone\(\)` + --> $DIR/weird-syntax.rs:68:9 + | +LL | /// [x][Clone\(\)] + | ^^^^^^^^^ no item named `Clone\(\)` in scope + | + = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` + error: unresolved link to `Clone` --> $DIR/weird-syntax.rs:74:9 | @@ -299,5 +307,5 @@ LL | /// - [`SDL_PROP_WINDOW_CREATE_COCOA_WINDOW_POINTER`]: the | = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]` -error: aborting due to 27 previous errors +error: aborting due to 28 previous errors From bd85df192d07660511b711cd7d4cae5b5a85577a Mon Sep 17 00:00:00 2001 From: binarycat Date: Sat, 19 Apr 2025 10:51:40 -0500 Subject: [PATCH 6/7] move bad-intra-doc test into intra-doc dir --- tests/rustdoc-ui/{ => intra-doc}/bad-intra-doc.rs | 0 tests/rustdoc-ui/{ => intra-doc}/bad-intra-doc.stderr | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename tests/rustdoc-ui/{ => intra-doc}/bad-intra-doc.rs (100%) rename tests/rustdoc-ui/{ => intra-doc}/bad-intra-doc.stderr (100%) diff --git a/tests/rustdoc-ui/bad-intra-doc.rs b/tests/rustdoc-ui/intra-doc/bad-intra-doc.rs similarity index 100% rename from tests/rustdoc-ui/bad-intra-doc.rs rename to tests/rustdoc-ui/intra-doc/bad-intra-doc.rs diff --git a/tests/rustdoc-ui/bad-intra-doc.stderr b/tests/rustdoc-ui/intra-doc/bad-intra-doc.stderr similarity index 100% rename from tests/rustdoc-ui/bad-intra-doc.stderr rename to tests/rustdoc-ui/intra-doc/bad-intra-doc.stderr From a73d7e3ab9cc29cb427c1463d1a02b89dd7728b6 Mon Sep 17 00:00:00 2001 From: binarycat Date: Thu, 24 Jul 2025 12:37:46 -0500 Subject: [PATCH 7/7] fix up issues with internal compiler docs revealed by stricter lint --- compiler/rustc_mir_transform/src/elaborate_drop.rs | 4 ++++ compiler/rustc_thread_pool/src/sleep/mod.rs | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_mir_transform/src/elaborate_drop.rs b/compiler/rustc_mir_transform/src/elaborate_drop.rs index de96b1f255a6e..de60772b17ea2 100644 --- a/compiler/rustc_mir_transform/src/elaborate_drop.rs +++ b/compiler/rustc_mir_transform/src/elaborate_drop.rs @@ -611,6 +611,7 @@ where /// /// For example, with 3 fields, the drop ladder is /// + /// ```text /// .d0: /// ELAB(drop location.0 [target=.d1, unwind=.c1]) /// .d1: @@ -621,8 +622,10 @@ where /// ELAB(drop location.1 [target=.c2]) /// .c2: /// ELAB(drop location.2 [target=`self.unwind`]) + /// ``` /// /// For possible-async drops in coroutines we also need dropline ladder + /// ```text /// .d0 (mainline): /// ELAB(drop location.0 [target=.d1, unwind=.c1, drop=.e1]) /// .d1 (mainline): @@ -637,6 +640,7 @@ where /// ELAB(drop location.1 [target=.e2, unwind=.c2]) /// .e2 (dropline): /// ELAB(drop location.2 [target=`self.drop`, unwind=`self.unwind`]) + /// ``` /// /// NOTE: this does not clear the master drop flag, so you need /// to point succ/unwind on a `drop_ladder_bottom`. diff --git a/compiler/rustc_thread_pool/src/sleep/mod.rs b/compiler/rustc_thread_pool/src/sleep/mod.rs index 31bf7184b42d5..aa6666092147a 100644 --- a/compiler/rustc_thread_pool/src/sleep/mod.rs +++ b/compiler/rustc_thread_pool/src/sleep/mod.rs @@ -44,7 +44,7 @@ impl SleepData { /// jobs are published, and it either blocks threads or wakes them in response to these /// events. See the [`README.md`] in this module for more details. /// -/// [`README.md`] README.md +/// [`README.md`]: README.md pub(super) struct Sleep { /// One "sleep state" per worker. Used to track if a worker is sleeping and to have /// them block.