diff --git a/CHANGELOG.md b/CHANGELOG.md index dd3124ee9a3b..7c404e790c8e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5441,6 +5441,7 @@ Released 2018-09-13 [`disallowed_type`]: https://rust-lang.github.io/rust-clippy/master/index.html#disallowed_type [`disallowed_types`]: https://rust-lang.github.io/rust-clippy/master/index.html#disallowed_types [`diverging_sub_expression`]: https://rust-lang.github.io/rust-clippy/master/index.html#diverging_sub_expression +[`doc_broken_link`]: https://rust-lang.github.io/rust-clippy/master/index.html#doc_broken_link [`doc_lazy_continuation`]: https://rust-lang.github.io/rust-clippy/master/index.html#doc_lazy_continuation [`doc_link_with_quotes`]: https://rust-lang.github.io/rust-clippy/master/index.html#doc_link_with_quotes [`doc_markdown`]: https://rust-lang.github.io/rust-clippy/master/index.html#doc_markdown diff --git a/clippy_lints/src/declared_lints.rs b/clippy_lints/src/declared_lints.rs index dff60f76b746..8b1ad45e17a4 100644 --- a/clippy_lints/src/declared_lints.rs +++ b/clippy_lints/src/declared_lints.rs @@ -135,6 +135,7 @@ pub static LINTS: &[&crate::LintInfo] = &[ crate::disallowed_names::DISALLOWED_NAMES_INFO, crate::disallowed_script_idents::DISALLOWED_SCRIPT_IDENTS_INFO, crate::disallowed_types::DISALLOWED_TYPES_INFO, + crate::doc::DOC_BROKEN_LINK_INFO, crate::doc::DOC_LAZY_CONTINUATION_INFO, crate::doc::DOC_LINK_WITH_QUOTES_INFO, crate::doc::DOC_MARKDOWN_INFO, diff --git a/clippy_lints/src/doc/broken_link.rs b/clippy_lints/src/doc/broken_link.rs new file mode 100644 index 000000000000..c9d56d5698ed --- /dev/null +++ b/clippy_lints/src/doc/broken_link.rs @@ -0,0 +1,14 @@ +use super::{DOC_BROKEN_LINK, Fragments}; +use clippy_utils::diagnostics::span_lint; +use rustc_lint::LateContext; +use std::ops::Range; + +// Check broken links in code docs. +pub fn check(cx: &LateContext<'_>, _trimmed_text: &str, range: Range, fragments: Fragments<'_>, link: &str) { + if let Some(span) = fragments.span(cx, range) { + // Broken links are replaced with "fake" value by `fake_broken_link_callback` at `doc/mod.rs`. + if link == "fake" { + span_lint(cx, DOC_BROKEN_LINK, span, "possible broken doc link"); + } + } +} diff --git a/clippy_lints/src/doc/mod.rs b/clippy_lints/src/doc/mod.rs index df7c37a192ad..c5f10ee03afd 100644 --- a/clippy_lints/src/doc/mod.rs +++ b/clippy_lints/src/doc/mod.rs @@ -32,6 +32,7 @@ use rustc_span::{Span, sym}; use std::ops::Range; use url::Url; +mod broken_link; mod empty_line_after; mod link_with_quotes; mod markdown; @@ -261,6 +262,33 @@ declare_clippy_lint! { "possible typo for an intra-doc link" } +declare_clippy_lint! { + /// ### What it does + /// Checks the doc comments have unbroken links, mostly caused + /// by bad formatted links such as broken across multiple lines. + /// + /// ### Why is this bad? + /// Because documentation generated by rustdoc will be broken + /// since expected links won't be links and just text. + /// + /// ### Examples + /// This link is broken: + /// ```no_run + /// /// [example of a bad link](https:// + /// /// github.com/rust-lang/rust-clippy/) + /// pub fn do_something() {} + /// + /// It shouldn't be broken across multiple lines to work: + /// ```no_run + /// /// [example of a good link](https://github.com/rust-lang/rust-clippy/) + /// pub fn do_something() {} + /// ``` + #[clippy::version = "1.82.0"] + pub DOC_BROKEN_LINK, + pedantic, + "broken document link" +} + declare_clippy_lint! { /// ### What it does /// Checks for the doc comments of publicly visible @@ -548,6 +576,7 @@ impl Documentation { impl_lint_pass!(Documentation => [ DOC_LINK_WITH_QUOTES, + DOC_BROKEN_LINK, DOC_MARKDOWN, MISSING_SAFETY_DOC, MISSING_ERRORS_DOC, @@ -929,6 +958,9 @@ fn check_doc<'a, Events: Iterator, Range tests/ui/doc_broken_link.rs:27:6 + | +LL | /// [doc invalid link broken url scheme part part](https:// + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `-D clippy::doc-broken-link` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::doc_broken_link)]` + +error: possible broken doc link + --> tests/ui/doc_broken_link.rs:33:6 + | +LL | /// [doc invalid link broken url host part](https://test + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors +