From 7bef775fd7ed95e48c5e8944d57b3e9c43583a14 Mon Sep 17 00:00:00 2001 From: Jacher Date: Sat, 1 Jun 2024 15:44:27 +0000 Subject: [PATCH 1/9] new restriction lint: `doc_comment_double_space_linebreak` --- CHANGELOG.md | 1 + clippy_lints/src/declared_lints.rs | 1 + .../doc/doc_comment_double_space_linebreak.rs | 100 ++++++++++++++++++ clippy_lints/src/doc/mod.rs | 56 +++++++++- .../doc_comment_double_space_linebreak.fixed | 43 ++++++++ .../doc/doc_comment_double_space_linebreak.rs | 43 ++++++++ .../doc_comment_double_space_linebreak.stderr | 24 +++++ 7 files changed, 266 insertions(+), 2 deletions(-) create mode 100644 clippy_lints/src/doc/doc_comment_double_space_linebreak.rs create mode 100644 tests/ui/doc/doc_comment_double_space_linebreak.fixed create mode 100644 tests/ui/doc/doc_comment_double_space_linebreak.rs create mode 100644 tests/ui/doc/doc_comment_double_space_linebreak.stderr diff --git a/CHANGELOG.md b/CHANGELOG.md index 682c3cfe0151..de7403a92585 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5351,6 +5351,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_comment_double_space_linebreak`]: https://rust-lang.github.io/rust-clippy/master/index.html#doc_comment_double_space_linebreak [`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 aded9e276c4a..caed64fea649 100644 --- a/clippy_lints/src/declared_lints.rs +++ b/clippy_lints/src/declared_lints.rs @@ -132,6 +132,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_COMMENT_DOUBLE_SPACE_LINEBREAK_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/doc_comment_double_space_linebreak.rs b/clippy_lints/src/doc/doc_comment_double_space_linebreak.rs new file mode 100644 index 000000000000..039ce6aabc5c --- /dev/null +++ b/clippy_lints/src/doc/doc_comment_double_space_linebreak.rs @@ -0,0 +1,100 @@ +use std::borrow::Cow; + +use clippy_utils::diagnostics::span_lint_and_then; +use clippy_utils::source::snippet; +use pulldown_cmark::CowStr; +use rustc_errors::Applicability; +use rustc_lint::LateContext; +use rustc_span::Span; + +use super::DOC_COMMENT_DOUBLE_SPACE_LINEBREAK; + +pub fn check(cx: &LateContext<'_>, collected_breaks: Vec<(Span, (Span, CowStr<'_>), Cow<'_, str>)>) { + let replacements: Vec<_> = collect_doc_replacements(cx, &collected_breaks); + + if let Some((&(lo_span, _), &(hi_span, _))) = replacements.first().zip(replacements.last()) { + span_lint_and_then( + cx, + DOC_COMMENT_DOUBLE_SPACE_LINEBREAK, + lo_span.to(hi_span), + "doc comments should use a back-slash (\\) instead of a double space to indicate a linebreak", + |diag| { + diag.multipart_suggestion( + "replace this double space with a back-slash", + replacements, + Applicability::MachineApplicable, + ); + }, + ); + } +} + +fn collect_doc_replacements( + cx: &LateContext<'_>, + attrs: &[(Span, (Span, CowStr<'_>), Cow<'_, str>)], +) -> Vec<(Span, String)> { + attrs + .iter() + .map(|attr| { + let full = attr.0; + let new_comment = format!("\\\n/// "); + (full, new_comment) + }) + .collect() +} + +/* +use clippy_utils::diagnostics::span_lint_and_then; +use rustc_ast::token::CommentKind; +use rustc_ast::{AttrKind, AttrStyle, Attribute}; +use rustc_errors::Applicability; +use rustc_lint::LateContext; +use rustc_span::Span; + +use super::DOC_COMMENT_DOUBLE_SPACE_LINEBREAK; + +pub fn check(cx: &LateContext<'_>, attrs: &[Attribute]) { + let replacements: Vec<_> = collect_doc_replacements(attrs); + + if let Some((&(lo_span, _), &(hi_span, _))) = replacements.first().zip(replacements.last()) { + span_lint_and_then( + cx, + DOC_COMMENT_DOUBLE_SPACE_LINEBREAK, + lo_span.to(hi_span), + "doc comments should use a back-slash (\\) instead of a double space to indicate a linebreak", + |diag| { + diag.multipart_suggestion( + "replace this double space with a back-slash", + replacements, + Applicability::MachineApplicable, + ); + }, + ); + } +} + +fn collect_doc_replacements(attrs: &[Attribute]) -> Vec<(Span, String)> { + attrs + .iter() + .filter_map(|attr| { + if let AttrKind::DocComment(com_kind, sym) = attr.kind + && !attr.span.from_expansion() + && com_kind == CommentKind::Line + && let comment = sym.as_str() + && comment.ends_with(" ") + { + let pre = match attr.style { + AttrStyle::Outer => "///", + AttrStyle::Inner => "//!", + }; + + let len = comment.len(); + let new_comment = format!("{pre}{}\\", &comment[..len - 2]); + Some((attr.span, new_comment)) + } else { + None + } + }) + .collect() +} +*/ diff --git a/clippy_lints/src/doc/mod.rs b/clippy_lints/src/doc/mod.rs index 6db63b59e020..0ed80d3c429e 100644 --- a/clippy_lints/src/doc/mod.rs +++ b/clippy_lints/src/doc/mod.rs @@ -5,6 +5,7 @@ use clippy_config::Conf; use clippy_utils::attrs::is_doc_hidden; use clippy_utils::diagnostics::{span_lint, span_lint_and_help}; use clippy_utils::macros::{is_panic, root_macro_call_first_node}; +use clippy_utils::source::snippet; use clippy_utils::ty::is_type_diagnostic_item; use clippy_utils::visitors::Visitable; use clippy_utils::{is_entrypoint_fn, is_trait_impl_item, method_chain_args}; @@ -29,10 +30,12 @@ use rustc_resolve::rustdoc::{ use rustc_session::impl_lint_pass; use rustc_span::edition::Edition; use rustc_span::{sym, Span}; +use std::borrow::Cow; use std::ops::Range; use url::Url; mod empty_line_after; +mod doc_comment_double_space_linebreak; mod link_with_quotes; mod markdown; mod missing_headers; @@ -532,6 +535,38 @@ declare_clippy_lint! { "empty line after doc comments" } +declare_clippy_lint! { + /// Detects doc comment linebreaks that use double spaces to separate lines, instead of back-slash (\). + /// + /// ### Why is this bad? + /// Double spaces, when used as doc comment linebreaks, can be difficult to see, and may + /// accidentally be removed during automatic fofmatting or manual refactoring. The use of a back-slash (\) + /// is clearer in this regard. + /// + /// ### Example + /// The two dots in this example represent a double space. + /// ```no_run + /// /// This command takes two numbers as inputs and.. + /// /// adds them together, and then returns the result. + /// fn add(l: i32, r: i32) -> i32 { + /// l + r + /// } + /// `````` + /// + /// Use instead: + /// ```no_run + /// /// This command takes two numbers as inputs and \ + /// /// adds them together, and then returns the result. + /// fn add(l: i32, r: i32) -> i32 { + /// l + r + /// } + /// ``` + #[clippy::version = "1.80.0"] + pub DOC_COMMENT_DOUBLE_SPACE_LINEBREAK, + restriction, + "double-space used for doc comment linebreak instead of `\\`" +} + pub struct Documentation { valid_idents: FxHashSet, check_private_items: bool, @@ -561,6 +596,7 @@ impl_lint_pass!(Documentation => [ EMPTY_LINE_AFTER_OUTER_ATTR, EMPTY_LINE_AFTER_DOC_COMMENTS, TOO_LONG_FIRST_DOC_PARAGRAPH, + DOC_COMMENT_DOUBLE_SPACE_LINEBREAK ]); impl<'tcx> LateLintPass<'tcx> for Documentation { @@ -694,6 +730,8 @@ fn check_attrs(cx: &LateContext<'_>, valid_idents: &FxHashSet, attrs: &[ return None; } + suspicious_doc_comments::check(cx, attrs); + let (fragments, _) = attrs_to_doc_fragments( attrs.iter().filter_map(|attr| { if in_external_macro(cx.sess(), attr.span) { @@ -776,8 +814,7 @@ fn check_doc<'a, Events: Iterator, Range), Cow<'_, str>)> = Vec::new(); let mut containers = Vec::new(); let mut events = events.peekable(); @@ -894,8 +931,20 @@ fn check_doc<'a, Events: Iterator, Range { + if let Some(span) = fragments.span(cx, range.clone()) { + prev_text = Some((span, text.clone())); + } paragraph_range.end = range.end; let range_ = range.clone(); ticks_unbalanced |= text.contains('`') @@ -943,6 +992,9 @@ fn check_doc<'a, Events: Iterator, Range {} } } + + doc_comment_double_space_linebreak::check(cx, collected_breaks); + headers } diff --git a/tests/ui/doc/doc_comment_double_space_linebreak.fixed b/tests/ui/doc/doc_comment_double_space_linebreak.fixed new file mode 100644 index 000000000000..f118ab3f47c9 --- /dev/null +++ b/tests/ui/doc/doc_comment_double_space_linebreak.fixed @@ -0,0 +1,43 @@ +#![feature(custom_inner_attributes)] +#![rustfmt::skip] + +#![warn(clippy::doc_comment_double_space_linebreak)] +#![allow(unused)] + +//! Should warn on double space linebreaks \ +//! in file/module doc comment + +/// Should not warn on single-line doc comments +fn single_line() {} + +/// Should not warn on single-line doc comments +/// split across multiple lines +fn single_line_split() {} + +// Should not warn on normal comments + +// note: cargo fmt can remove double spaces from normal and block comments +// Should not warn on normal comments +// with double spaces at the end of a line + +fn normal_comment() { + /* + Should not warn on block comments + */ + + /* + Should not warn on block comments + with double space at the end of a line + */ +} + +/// Should warn when doc comment uses double space \ +/// as a line-break, even when there are multiple \ +/// in a row +fn double_space_doc_comment() {} + +/// Should not warn when back-slash is used \ +/// as a line-break +fn back_slash_doc_comment() {} + +fn main() {} diff --git a/tests/ui/doc/doc_comment_double_space_linebreak.rs b/tests/ui/doc/doc_comment_double_space_linebreak.rs new file mode 100644 index 000000000000..95f036154f7c --- /dev/null +++ b/tests/ui/doc/doc_comment_double_space_linebreak.rs @@ -0,0 +1,43 @@ +#![feature(custom_inner_attributes)] +#![rustfmt::skip] + +#![warn(clippy::doc_comment_double_space_linebreak)] +#![allow(unused)] + +//! Should warn on double space linebreaks +//! in file/module doc comment + +/// Should not warn on single-line doc comments +fn single_line() {} + +/// Should not warn on single-line doc comments +/// split across multiple lines +fn single_line_split() {} + +// Should not warn on normal comments + +// note: cargo fmt can remove double spaces from normal and block comments +// Should not warn on normal comments +// with double spaces at the end of a line + +fn normal_comment() { + /* + Should not warn on block comments + */ + + /* + Should not warn on block comments + with double space at the end of a line + */ +} + +/// Should warn when doc comment uses double space +/// as a line-break, even when there are multiple +/// in a row +fn double_space_doc_comment() {} + +/// Should not warn when back-slash is used \ +/// as a line-break +fn back_slash_doc_comment() {} + +fn main() {} diff --git a/tests/ui/doc/doc_comment_double_space_linebreak.stderr b/tests/ui/doc/doc_comment_double_space_linebreak.stderr new file mode 100644 index 000000000000..ddc12695edc0 --- /dev/null +++ b/tests/ui/doc/doc_comment_double_space_linebreak.stderr @@ -0,0 +1,24 @@ +error: doc comments should use a back-slash (\) instead of a double space to indicate a linebreak + --> tests/ui/doc/doc_comment_double_space_linebreak.rs:7:1 + | +LL | //! Should warn on double space linebreaks + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace this double space with a back-slash: `//! Should warn on double space linebreaks \` + | + = note: `-D clippy::doc-comment-double-space-linebreak` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::doc_comment_double_space_linebreak)]` + +error: doc comments should use a back-slash (\) instead of a double space to indicate a linebreak + --> tests/ui/doc/doc_comment_double_space_linebreak.rs:34:1 + | +LL | / /// Should warn when doc comment uses double space +LL | | /// as a line-break, even when there are multiple + | |___________________________________________________^ + | +help: replace this double space with a back-slash + | +LL + /// Should warn when doc comment uses double space \ +LL + /// as a line-break, even when there are multiple \ + | + +error: aborting due to 2 previous errors + From d7bb6007fb65e173b4b021c021a7dae4e7f8316a Mon Sep 17 00:00:00 2001 From: Jacher Date: Sat, 1 Jun 2024 15:48:23 +0000 Subject: [PATCH 2/9] fix typo --- clippy_lints/src/doc/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clippy_lints/src/doc/mod.rs b/clippy_lints/src/doc/mod.rs index 0ed80d3c429e..85190fbf094c 100644 --- a/clippy_lints/src/doc/mod.rs +++ b/clippy_lints/src/doc/mod.rs @@ -540,7 +540,7 @@ declare_clippy_lint! { /// /// ### Why is this bad? /// Double spaces, when used as doc comment linebreaks, can be difficult to see, and may - /// accidentally be removed during automatic fofmatting or manual refactoring. The use of a back-slash (\) + /// accidentally be removed during automatic formatting or manual refactoring. The use of a back-slash (\) /// is clearer in this regard. /// /// ### Example From 1e69f82396c618ecd2e367e06984cccba1cc376c Mon Sep 17 00:00:00 2001 From: Jacher Date: Sat, 1 Jun 2024 17:12:40 +0000 Subject: [PATCH 3/9] change replacement character in example, remove extraneous space from suggested change --- clippy_lints/src/doc/mod.rs | 4 ++-- tests/ui/doc/doc_comment_double_space_linebreak.fixed | 6 +++--- tests/ui/doc/doc_comment_double_space_linebreak.stderr | 6 +++--- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/clippy_lints/src/doc/mod.rs b/clippy_lints/src/doc/mod.rs index 85190fbf094c..e243c861ce2c 100644 --- a/clippy_lints/src/doc/mod.rs +++ b/clippy_lints/src/doc/mod.rs @@ -544,9 +544,9 @@ declare_clippy_lint! { /// is clearer in this regard. /// /// ### Example - /// The two dots in this example represent a double space. + /// The two replacement dots in this example represent a double space. /// ```no_run - /// /// This command takes two numbers as inputs and.. + /// /// This command takes two numbers as inputs andΒ·Β· /// /// adds them together, and then returns the result. /// fn add(l: i32, r: i32) -> i32 { /// l + r diff --git a/tests/ui/doc/doc_comment_double_space_linebreak.fixed b/tests/ui/doc/doc_comment_double_space_linebreak.fixed index f118ab3f47c9..d70932445873 100644 --- a/tests/ui/doc/doc_comment_double_space_linebreak.fixed +++ b/tests/ui/doc/doc_comment_double_space_linebreak.fixed @@ -4,7 +4,7 @@ #![warn(clippy::doc_comment_double_space_linebreak)] #![allow(unused)] -//! Should warn on double space linebreaks \ +//! Should warn on double space linebreaks\ //! in file/module doc comment /// Should not warn on single-line doc comments @@ -31,8 +31,8 @@ fn normal_comment() { */ } -/// Should warn when doc comment uses double space \ -/// as a line-break, even when there are multiple \ +/// Should warn when doc comment uses double space\ +/// as a line-break, even when there are multiple\ /// in a row fn double_space_doc_comment() {} diff --git a/tests/ui/doc/doc_comment_double_space_linebreak.stderr b/tests/ui/doc/doc_comment_double_space_linebreak.stderr index ddc12695edc0..d1b3cf39527d 100644 --- a/tests/ui/doc/doc_comment_double_space_linebreak.stderr +++ b/tests/ui/doc/doc_comment_double_space_linebreak.stderr @@ -2,7 +2,7 @@ error: doc comments should use a back-slash (\) instead of a double space to ind --> tests/ui/doc/doc_comment_double_space_linebreak.rs:7:1 | LL | //! Should warn on double space linebreaks - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace this double space with a back-slash: `//! Should warn on double space linebreaks \` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace this double space with a back-slash: `//! Should warn on double space linebreaks\` | = note: `-D clippy::doc-comment-double-space-linebreak` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::doc_comment_double_space_linebreak)]` @@ -16,8 +16,8 @@ LL | | /// as a line-break, even when there are multiple | help: replace this double space with a back-slash | -LL + /// Should warn when doc comment uses double space \ -LL + /// as a line-break, even when there are multiple \ +LL + /// Should warn when doc comment uses double space\ +LL + /// as a line-break, even when there are multiple\ | error: aborting due to 2 previous errors From 42ad278cdd262739772d756430046a92c0eb9de5 Mon Sep 17 00:00:00 2001 From: Jacherr Date: Thu, 27 Jun 2024 12:15:08 +0100 Subject: [PATCH 4/9] add additional testcases; check doc comment not from expansion --- clippy_lints/src/doc/mod.rs | 4 ++-- .../doc_comment_double_space_linebreak.fixed | 20 +++++++++++++++++- .../doc/doc_comment_double_space_linebreak.rs | 20 +++++++++++++++++- .../doc_comment_double_space_linebreak.stderr | 21 +++++++++++++++++-- 4 files changed, 59 insertions(+), 6 deletions(-) diff --git a/clippy_lints/src/doc/mod.rs b/clippy_lints/src/doc/mod.rs index e243c861ce2c..904968c1cdc7 100644 --- a/clippy_lints/src/doc/mod.rs +++ b/clippy_lints/src/doc/mod.rs @@ -551,7 +551,7 @@ declare_clippy_lint! { /// fn add(l: i32, r: i32) -> i32 { /// l + r /// } - /// `````` + /// ``` /// /// Use instead: /// ```no_run @@ -563,7 +563,7 @@ declare_clippy_lint! { /// ``` #[clippy::version = "1.80.0"] pub DOC_COMMENT_DOUBLE_SPACE_LINEBREAK, - restriction, + pedantic, "double-space used for doc comment linebreak instead of `\\`" } diff --git a/tests/ui/doc/doc_comment_double_space_linebreak.fixed b/tests/ui/doc/doc_comment_double_space_linebreak.fixed index d70932445873..a2beefdd8430 100644 --- a/tests/ui/doc/doc_comment_double_space_linebreak.fixed +++ b/tests/ui/doc/doc_comment_double_space_linebreak.fixed @@ -18,8 +18,9 @@ fn single_line_split() {} // note: cargo fmt can remove double spaces from normal and block comments // Should not warn on normal comments -// with double spaces at the end of a line +// with double spaces at the end of a line +#[doc = "This is a doc attribute, which should not be linted"] fn normal_comment() { /* Should not warn on block comments @@ -40,4 +41,21 @@ fn double_space_doc_comment() {} /// as a line-break fn back_slash_doc_comment() {} +/// 🌹 are πŸŸ₯\ +/// 🌷 are 🟦\ +/// πŸ“Ž is 😎\ +/// and so are 🫡\ +/// (hopefully no formatting weirdness linting this) +fn multi_byte_chars_tada() {} + +macro_rules! macro_that_makes_function { + () => { + /// Shouldn't lint on this! + /// (hopefully) + fn my_macro_created_function() {} + } +} + +macro_that_makes_function!(); + fn main() {} diff --git a/tests/ui/doc/doc_comment_double_space_linebreak.rs b/tests/ui/doc/doc_comment_double_space_linebreak.rs index 95f036154f7c..4be1c2d9ff70 100644 --- a/tests/ui/doc/doc_comment_double_space_linebreak.rs +++ b/tests/ui/doc/doc_comment_double_space_linebreak.rs @@ -18,8 +18,9 @@ fn single_line_split() {} // note: cargo fmt can remove double spaces from normal and block comments // Should not warn on normal comments -// with double spaces at the end of a line +// with double spaces at the end of a line +#[doc = "This is a doc attribute, which should not be linted"] fn normal_comment() { /* Should not warn on block comments @@ -40,4 +41,21 @@ fn double_space_doc_comment() {} /// as a line-break fn back_slash_doc_comment() {} +/// 🌹 are πŸŸ₯ +/// 🌷 are 🟦 +/// πŸ“Ž is 😎 +/// and so are 🫡 +/// (hopefully no formatting weirdness linting this) +fn multi_byte_chars_tada() {} + +macro_rules! macro_that_makes_function { + () => { + /// Shouldn't lint on this! + /// (hopefully) + fn my_macro_created_function() {} + } +} + +macro_that_makes_function!(); + fn main() {} diff --git a/tests/ui/doc/doc_comment_double_space_linebreak.stderr b/tests/ui/doc/doc_comment_double_space_linebreak.stderr index d1b3cf39527d..b008325226e8 100644 --- a/tests/ui/doc/doc_comment_double_space_linebreak.stderr +++ b/tests/ui/doc/doc_comment_double_space_linebreak.stderr @@ -8,7 +8,7 @@ LL | //! Should warn on double space linebreaks = help: to override `-D warnings` add `#[allow(clippy::doc_comment_double_space_linebreak)]` error: doc comments should use a back-slash (\) instead of a double space to indicate a linebreak - --> tests/ui/doc/doc_comment_double_space_linebreak.rs:34:1 + --> tests/ui/doc/doc_comment_double_space_linebreak.rs:35:1 | LL | / /// Should warn when doc comment uses double space LL | | /// as a line-break, even when there are multiple @@ -20,5 +20,22 @@ LL + /// Should warn when doc comment uses double space\ LL + /// as a line-break, even when there are multiple\ | -error: aborting due to 2 previous errors +error: doc comments should use a back-slash (\) instead of a double space to indicate a linebreak + --> tests/ui/doc/doc_comment_double_space_linebreak.rs:44:1 + | +LL | / /// 🌹 are πŸŸ₯ +LL | | /// 🌷 are 🟦 +LL | | /// πŸ“Ž is 😎 +LL | | /// and so are 🫡 + | |___________________^ + | +help: replace this double space with a back-slash + | +LL ~ /// 🌹 are πŸŸ₯\ +LL ~ /// 🌷 are 🟦\ +LL ~ /// πŸ“Ž is 😎\ +LL ~ /// and so are 🫡\ + | + +error: aborting due to 3 previous errors From e646eda4eb7ddcf562e9438859218e438e62d086 Mon Sep 17 00:00:00 2001 From: Jacherr Date: Fri, 9 Aug 2024 19:56:53 +0100 Subject: [PATCH 5/9] do not lint on macros, add more testcases --- .../doc/doc_comment_double_space_linebreak.rs | 24 ++++++------- clippy_lints/src/doc/mod.rs | 20 +++++------ .../doc_comment_double_space_linebreak.fixed | 27 +++++++++++++- .../doc/doc_comment_double_space_linebreak.rs | 27 +++++++++++++- .../doc_comment_double_space_linebreak.stderr | 35 +++++++++++++------ 5 files changed, 94 insertions(+), 39 deletions(-) diff --git a/clippy_lints/src/doc/doc_comment_double_space_linebreak.rs b/clippy_lints/src/doc/doc_comment_double_space_linebreak.rs index 039ce6aabc5c..708e4282065a 100644 --- a/clippy_lints/src/doc/doc_comment_double_space_linebreak.rs +++ b/clippy_lints/src/doc/doc_comment_double_space_linebreak.rs @@ -1,16 +1,13 @@ -use std::borrow::Cow; - use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::source::snippet; -use pulldown_cmark::CowStr; use rustc_errors::Applicability; use rustc_lint::LateContext; use rustc_span::Span; use super::DOC_COMMENT_DOUBLE_SPACE_LINEBREAK; -pub fn check(cx: &LateContext<'_>, collected_breaks: Vec<(Span, (Span, CowStr<'_>), Cow<'_, str>)>) { - let replacements: Vec<_> = collect_doc_replacements(cx, &collected_breaks); +pub fn check(cx: &LateContext<'_>, collected_breaks: &[Span]) { + let replacements: Vec<_> = collect_doc_replacements(cx, collected_breaks); if let Some((&(lo_span, _), &(hi_span, _))) = replacements.first().zip(replacements.last()) { span_lint_and_then( @@ -29,16 +26,15 @@ pub fn check(cx: &LateContext<'_>, collected_breaks: Vec<(Span, (Span, CowStr<'_ } } -fn collect_doc_replacements( - cx: &LateContext<'_>, - attrs: &[(Span, (Span, CowStr<'_>), Cow<'_, str>)], -) -> Vec<(Span, String)> { - attrs +fn collect_doc_replacements(cx: &LateContext<'_>, spans: &[Span]) -> Vec<(Span, String)> { + spans .iter() - .map(|attr| { - let full = attr.0; - let new_comment = format!("\\\n/// "); - (full, new_comment) + .map(|span| { + let s = snippet(cx, *span, ".."); + let after_newline = s.trim_start_matches(' '); + + let new_comment = format!("\\{after_newline}"); + (*span, new_comment) }) .collect() } diff --git a/clippy_lints/src/doc/mod.rs b/clippy_lints/src/doc/mod.rs index 904968c1cdc7..9b9341236f04 100644 --- a/clippy_lints/src/doc/mod.rs +++ b/clippy_lints/src/doc/mod.rs @@ -30,12 +30,11 @@ use rustc_resolve::rustdoc::{ use rustc_session::impl_lint_pass; use rustc_span::edition::Edition; use rustc_span::{sym, Span}; -use std::borrow::Cow; use std::ops::Range; use url::Url; -mod empty_line_after; mod doc_comment_double_space_linebreak; +mod empty_line_after; mod link_with_quotes; mod markdown; mod missing_headers; @@ -814,7 +813,8 @@ fn check_doc<'a, Events: Iterator, Range), Cow<'_, str>)> = Vec::new(); + let mut collected_breaks: Vec = Vec::new(); + let mut containers = Vec::new(); let mut events = events.peekable(); @@ -932,19 +932,15 @@ fn check_doc<'a, Events: Iterator, Range { - if let Some(span) = fragments.span(cx, range.clone()) { - prev_text = Some((span, text.clone())); - } paragraph_range.end = range.end; let range_ = range.clone(); ticks_unbalanced |= text.contains('`') @@ -993,7 +989,7 @@ fn check_doc<'a, Events: Iterator, Range tests/ui/doc/doc_comment_double_space_linebreak.rs:7:1 + --> tests/ui/doc/doc_comment_double_space_linebreak.rs:7:43 | -LL | //! Should warn on double space linebreaks - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace this double space with a back-slash: `//! Should warn on double space linebreaks\` +LL | //! Should warn on double space linebreaks + | ___________________________________________^ +LL | | //! in file/module doc comment + | |____^ | = note: `-D clippy::doc-comment-double-space-linebreak` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::doc_comment_double_space_linebreak)]` +help: replace this double space with a back-slash + | +LL ~ //! Should warn on double space linebreaks\ +LL ~ //! in file/module doc comment + | error: doc comments should use a back-slash (\) instead of a double space to indicate a linebreak - --> tests/ui/doc/doc_comment_double_space_linebreak.rs:35:1 + --> tests/ui/doc/doc_comment_double_space_linebreak.rs:35:51 | -LL | / /// Should warn when doc comment uses double space +LL | /// Should warn when doc comment uses double space + | ___________________________________________________^ LL | | /// as a line-break, even when there are multiple - | |___________________________________________________^ +LL | | /// in a row + | |____^ | help: replace this double space with a back-slash | -LL + /// Should warn when doc comment uses double space\ -LL + /// as a line-break, even when there are multiple\ +LL ~ /// Should warn when doc comment uses double space\ +LL ~ /// as a line-break, even when there are multiple\ +LL ~ /// in a row | error: doc comments should use a back-slash (\) instead of a double space to indicate a linebreak - --> tests/ui/doc/doc_comment_double_space_linebreak.rs:44:1 + --> tests/ui/doc/doc_comment_double_space_linebreak.rs:44:12 | -LL | / /// 🌹 are πŸŸ₯ +LL | /// 🌹 are πŸŸ₯ + | ______________^ LL | | /// 🌷 are 🟦 LL | | /// πŸ“Ž is 😎 LL | | /// and so are 🫡 - | |___________________^ +LL | | /// (hopefully no formatting weirdness linting this) + | |____^ | help: replace this double space with a back-slash | @@ -35,6 +47,7 @@ LL ~ /// 🌹 are πŸŸ₯\ LL ~ /// 🌷 are 🟦\ LL ~ /// πŸ“Ž is 😎\ LL ~ /// and so are 🫡\ +LL ~ /// (hopefully no formatting weirdness linting this) | error: aborting due to 3 previous errors From 7babc2aabfa498437cd78e5a202fdd9d3c169be7 Mon Sep 17 00:00:00 2001 From: Jacherr Date: Sat, 10 Aug 2024 12:20:33 +0100 Subject: [PATCH 6/9] fix wording, remove commented out code, add additonal testcase --- .../doc/doc_comment_double_space_linebreak.rs | 60 +------------------ .../doc/doc_comment_double_space_linebreak.rs | 8 +++ 2 files changed, 10 insertions(+), 58 deletions(-) diff --git a/clippy_lints/src/doc/doc_comment_double_space_linebreak.rs b/clippy_lints/src/doc/doc_comment_double_space_linebreak.rs index 708e4282065a..38fb2e07c111 100644 --- a/clippy_lints/src/doc/doc_comment_double_space_linebreak.rs +++ b/clippy_lints/src/doc/doc_comment_double_space_linebreak.rs @@ -14,10 +14,10 @@ pub fn check(cx: &LateContext<'_>, collected_breaks: &[Span]) { cx, DOC_COMMENT_DOUBLE_SPACE_LINEBREAK, lo_span.to(hi_span), - "doc comments should use a back-slash (\\) instead of a double space to indicate a linebreak", + "doc comment uses two spaces for a hard line break", |diag| { diag.multipart_suggestion( - "replace this double space with a back-slash", + "replace this double space with a backslash", replacements, Applicability::MachineApplicable, ); @@ -38,59 +38,3 @@ fn collect_doc_replacements(cx: &LateContext<'_>, spans: &[Span]) -> Vec<(Span, }) .collect() } - -/* -use clippy_utils::diagnostics::span_lint_and_then; -use rustc_ast::token::CommentKind; -use rustc_ast::{AttrKind, AttrStyle, Attribute}; -use rustc_errors::Applicability; -use rustc_lint::LateContext; -use rustc_span::Span; - -use super::DOC_COMMENT_DOUBLE_SPACE_LINEBREAK; - -pub fn check(cx: &LateContext<'_>, attrs: &[Attribute]) { - let replacements: Vec<_> = collect_doc_replacements(attrs); - - if let Some((&(lo_span, _), &(hi_span, _))) = replacements.first().zip(replacements.last()) { - span_lint_and_then( - cx, - DOC_COMMENT_DOUBLE_SPACE_LINEBREAK, - lo_span.to(hi_span), - "doc comments should use a back-slash (\\) instead of a double space to indicate a linebreak", - |diag| { - diag.multipart_suggestion( - "replace this double space with a back-slash", - replacements, - Applicability::MachineApplicable, - ); - }, - ); - } -} - -fn collect_doc_replacements(attrs: &[Attribute]) -> Vec<(Span, String)> { - attrs - .iter() - .filter_map(|attr| { - if let AttrKind::DocComment(com_kind, sym) = attr.kind - && !attr.span.from_expansion() - && com_kind == CommentKind::Line - && let comment = sym.as_str() - && comment.ends_with(" ") - { - let pre = match attr.style { - AttrStyle::Outer => "///", - AttrStyle::Inner => "//!", - }; - - let len = comment.len(); - let new_comment = format!("{pre}{}\\", &comment[..len - 2]); - Some((attr.span, new_comment)) - } else { - None - } - }) - .collect() -} -*/ diff --git a/tests/ui/doc/doc_comment_double_space_linebreak.rs b/tests/ui/doc/doc_comment_double_space_linebreak.rs index e4d3bbbe7d27..c64eedc24289 100644 --- a/tests/ui/doc/doc_comment_double_space_linebreak.rs +++ b/tests/ui/doc/doc_comment_double_space_linebreak.rs @@ -83,4 +83,12 @@ fn inline() {} /// https://example.com) in a URL. fn url() {} +/// here we mix +/// double spaces\ +/// and also +/// adding backslash\ +/// to some of them +/// to see how that looks +fn mixed() {} + fn main() {} From 451998063bf64db11596c9ae4408a3abdce037c1 Mon Sep 17 00:00:00 2001 From: Jacherr Date: Sat, 10 Aug 2024 12:21:46 +0100 Subject: [PATCH 7/9] uibless --- .../doc_comment_double_space_linebreak.fixed | 8 +++++ .../doc_comment_double_space_linebreak.stderr | 36 +++++++++++++++---- 2 files changed, 37 insertions(+), 7 deletions(-) diff --git a/tests/ui/doc/doc_comment_double_space_linebreak.fixed b/tests/ui/doc/doc_comment_double_space_linebreak.fixed index 99890e3bd096..efcd56809b7e 100644 --- a/tests/ui/doc/doc_comment_double_space_linebreak.fixed +++ b/tests/ui/doc/doc_comment_double_space_linebreak.fixed @@ -83,4 +83,12 @@ fn inline() {} /// https://example.com) in a URL. fn url() {} +/// here we mix\ +/// double spaces\ +/// and also\ +/// adding backslash\ +/// to some of them\ +/// to see how that looks +fn mixed() {} + fn main() {} diff --git a/tests/ui/doc/doc_comment_double_space_linebreak.stderr b/tests/ui/doc/doc_comment_double_space_linebreak.stderr index 3df3ed8007ad..4c77f8e15034 100644 --- a/tests/ui/doc/doc_comment_double_space_linebreak.stderr +++ b/tests/ui/doc/doc_comment_double_space_linebreak.stderr @@ -1,4 +1,4 @@ -error: doc comments should use a back-slash (\) instead of a double space to indicate a linebreak +error: doc comment uses two spaces for a hard line break --> tests/ui/doc/doc_comment_double_space_linebreak.rs:7:43 | LL | //! Should warn on double space linebreaks @@ -8,13 +8,13 @@ LL | | //! in file/module doc comment | = note: `-D clippy::doc-comment-double-space-linebreak` implied by `-D warnings` = help: to override `-D warnings` add `#[allow(clippy::doc_comment_double_space_linebreak)]` -help: replace this double space with a back-slash +help: replace this double space with a backslash | LL ~ //! Should warn on double space linebreaks\ LL ~ //! in file/module doc comment | -error: doc comments should use a back-slash (\) instead of a double space to indicate a linebreak +error: doc comment uses two spaces for a hard line break --> tests/ui/doc/doc_comment_double_space_linebreak.rs:35:51 | LL | /// Should warn when doc comment uses double space @@ -23,14 +23,14 @@ LL | | /// as a line-break, even when there are multiple LL | | /// in a row | |____^ | -help: replace this double space with a back-slash +help: replace this double space with a backslash | LL ~ /// Should warn when doc comment uses double space\ LL ~ /// as a line-break, even when there are multiple\ LL ~ /// in a row | -error: doc comments should use a back-slash (\) instead of a double space to indicate a linebreak +error: doc comment uses two spaces for a hard line break --> tests/ui/doc/doc_comment_double_space_linebreak.rs:44:12 | LL | /// 🌹 are πŸŸ₯ @@ -41,7 +41,7 @@ LL | | /// and so are 🫡 LL | | /// (hopefully no formatting weirdness linting this) | |____^ | -help: replace this double space with a back-slash +help: replace this double space with a backslash | LL ~ /// 🌹 are πŸŸ₯\ LL ~ /// 🌷 are 🟦\ @@ -50,5 +50,27 @@ LL ~ /// and so are 🫡\ LL ~ /// (hopefully no formatting weirdness linting this) | -error: aborting due to 3 previous errors +error: doc comment uses two spaces for a hard line break + --> tests/ui/doc/doc_comment_double_space_linebreak.rs:86:16 + | +LL | /// here we mix + | ________________^ +LL | | /// double spaces\ +LL | | /// and also +LL | | /// adding backslash\ +LL | | /// to some of them +LL | | /// to see how that looks + | |____^ + | +help: replace this double space with a backslash + | +LL ~ /// here we mix\ +LL ~ /// double spaces\ +LL ~ /// and also\ +LL ~ /// adding backslash\ +LL ~ /// to some of them\ +LL ~ /// to see how that looks + | + +error: aborting due to 4 previous errors From ef247f95b0d78dbc6ad948b865d14560b15bd7ad Mon Sep 17 00:00:00 2001 From: Jacherr Date: Tue, 3 Sep 2024 17:50:31 +0100 Subject: [PATCH 8/9] fix doc comments, use optional snippets --- .../src/doc/doc_comment_double_space_linebreak.rs | 5 +++-- clippy_lints/src/doc/mod.rs | 9 +++++---- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/clippy_lints/src/doc/doc_comment_double_space_linebreak.rs b/clippy_lints/src/doc/doc_comment_double_space_linebreak.rs index 38fb2e07c111..4c2475ad8d85 100644 --- a/clippy_lints/src/doc/doc_comment_double_space_linebreak.rs +++ b/clippy_lints/src/doc/doc_comment_double_space_linebreak.rs @@ -1,5 +1,5 @@ use clippy_utils::diagnostics::span_lint_and_then; -use clippy_utils::source::snippet; +use clippy_utils::source::snippet_opt; use rustc_errors::Applicability; use rustc_lint::LateContext; use rustc_span::Span; @@ -30,7 +30,8 @@ fn collect_doc_replacements(cx: &LateContext<'_>, spans: &[Span]) -> Vec<(Span, spans .iter() .map(|span| { - let s = snippet(cx, *span, ".."); + // we already made sure the snippet exists when collecting spans + let s = snippet_opt(cx, *span).expect("snippet was already validated to exist"); let after_newline = s.trim_start_matches(' '); let new_comment = format!("\\{after_newline}"); diff --git a/clippy_lints/src/doc/mod.rs b/clippy_lints/src/doc/mod.rs index 9b9341236f04..8c541aaf9725 100644 --- a/clippy_lints/src/doc/mod.rs +++ b/clippy_lints/src/doc/mod.rs @@ -5,7 +5,7 @@ use clippy_config::Conf; use clippy_utils::attrs::is_doc_hidden; use clippy_utils::diagnostics::{span_lint, span_lint_and_help}; use clippy_utils::macros::{is_panic, root_macro_call_first_node}; -use clippy_utils::source::snippet; +use clippy_utils::source::snippet_opt; use clippy_utils::ty::is_type_diagnostic_item; use clippy_utils::visitors::Visitable; use clippy_utils::{is_entrypoint_fn, is_trait_impl_item, method_chain_args}; @@ -535,11 +535,11 @@ declare_clippy_lint! { } declare_clippy_lint! { - /// Detects doc comment linebreaks that use double spaces to separate lines, instead of back-slash (\). + /// Detects doc comment linebreaks that use double spaces to separate lines, instead of back-slash (`\`). /// /// ### Why is this bad? /// Double spaces, when used as doc comment linebreaks, can be difficult to see, and may - /// accidentally be removed during automatic formatting or manual refactoring. The use of a back-slash (\) + /// accidentally be removed during automatic formatting or manual refactoring. The use of a back-slash (`\`) /// is clearer in this regard. /// /// ### Example @@ -814,6 +814,7 @@ fn check_doc<'a, Events: Iterator, Range = Vec::new(); + let mut is_first_paragraph = true; let mut containers = Vec::new(); @@ -934,7 +935,7 @@ fn check_doc<'a, Events: Iterator, Range Date: Tue, 10 Sep 2024 12:24:45 +0100 Subject: [PATCH 9/9] Remove unneeded additional space --- clippy_lints/src/doc/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clippy_lints/src/doc/mod.rs b/clippy_lints/src/doc/mod.rs index 8c541aaf9725..901ea33a650a 100644 --- a/clippy_lints/src/doc/mod.rs +++ b/clippy_lints/src/doc/mod.rs @@ -554,7 +554,7 @@ declare_clippy_lint! { /// /// Use instead: /// ```no_run - /// /// This command takes two numbers as inputs and \ + /// /// This command takes two numbers as inputs and\ /// /// adds them together, and then returns the result. /// fn add(l: i32, r: i32) -> i32 { /// l + r