@@ -32,6 +32,7 @@ use rustc_span::{Span, sym};
3232use std:: ops:: Range ;
3333use url:: Url ;
3434
35+ mod broken_link;
3536mod empty_line_after;
3637mod link_with_quotes;
3738mod markdown;
@@ -261,6 +262,33 @@ declare_clippy_lint! {
261262 "possible typo for an intra-doc link"
262263}
263264
265+ declare_clippy_lint ! {
266+ /// ### What it does
267+ /// Checks the doc comments have unbroken links, mostly caused
268+ /// by bad formatted links such as broken across multiple lines.
269+ ///
270+ /// ### Why is this bad?
271+ /// Because documentation generated by rustdoc will be broken
272+ /// since expected links won't be links and just text.
273+ ///
274+ /// ### Examples
275+ /// This link is broken:
276+ /// ```no_run
277+ /// /// [example of a bad link](https://
278+ /// /// github.com/rust-lang/rust-clippy/)
279+ /// pub fn do_something() {}
280+ ///
281+ /// It shouldn't be broken across multiple lines to work:
282+ /// ```no_run
283+ /// /// [example of a good link](https://github.com/rust-lang/rust-clippy/)
284+ /// pub fn do_something() {}
285+ /// ```
286+ #[ clippy:: version = "1.82.0" ]
287+ pub DOC_BROKEN_LINK ,
288+ pedantic,
289+ "broken document link"
290+ }
291+
264292declare_clippy_lint ! {
265293 /// ### What it does
266294 /// Checks for the doc comments of publicly visible
@@ -548,6 +576,7 @@ impl Documentation {
548576
549577impl_lint_pass ! ( Documentation => [
550578 DOC_LINK_WITH_QUOTES ,
579+ DOC_BROKEN_LINK ,
551580 DOC_MARKDOWN ,
552581 MISSING_SAFETY_DOC ,
553582 MISSING_ERRORS_DOC ,
@@ -929,6 +958,9 @@ fn check_doc<'a, Events: Iterator<Item = (pulldown_cmark::Event<'a>, Range<usize
929958 } else {
930959 if in_link. is_some ( ) {
931960 link_with_quotes:: check ( cx, trimmed_text, range. clone ( ) , fragments) ;
961+ if let Some ( link) = in_link. as_ref ( ) {
962+ broken_link:: check ( cx, trimmed_text, range. clone ( ) , fragments, & link) ;
963+ }
932964 }
933965 if let Some ( link) = in_link. as_ref ( )
934966 && let Ok ( url) = Url :: parse ( link)
0 commit comments