new lint: doc_comment_double_space_linebreak
fix typo change replacement character in example, remove extraneous space from suggested change add additional testcases; check doc comment not from expansion do not lint on macros, add more testcases fix wording, remove commented out code, add additonal testcase uibless fix doc comments, use optional snippets Remove unneeded additional space
This commit is contained in:
parent
1419ac2982
commit
f94f64f5e8
7 changed files with 356 additions and 0 deletions
|
|
@ -5571,6 +5571,7 @@ Released 2018-09-13
|
|||
[`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_include_without_cfg`]: https://rust-lang.github.io/rust-clippy/master/index.html#doc_include_without_cfg
|
||||
[`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_code`]: https://rust-lang.github.io/rust-clippy/master/index.html#doc_link_code
|
||||
[`doc_link_with_quotes`]: https://rust-lang.github.io/rust-clippy/master/index.html#doc_link_with_quotes
|
||||
|
|
|
|||
|
|
@ -138,6 +138,7 @@ pub static LINTS: &[&crate::LintInfo] = &[
|
|||
crate::disallowed_script_idents::DISALLOWED_SCRIPT_IDENTS_INFO,
|
||||
crate::disallowed_types::DISALLOWED_TYPES_INFO,
|
||||
crate::doc::DOC_INCLUDE_WITHOUT_CFG_INFO,
|
||||
crate::doc::DOC_COMMENT_DOUBLE_SPACE_LINEBREAK_INFO,
|
||||
crate::doc::DOC_LAZY_CONTINUATION_INFO,
|
||||
crate::doc::DOC_LINK_CODE_INFO,
|
||||
crate::doc::DOC_LINK_WITH_QUOTES_INFO,
|
||||
|
|
|
|||
41
clippy_lints/src/doc/doc_comment_double_space_linebreak.rs
Normal file
41
clippy_lints/src/doc/doc_comment_double_space_linebreak.rs
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
use clippy_utils::diagnostics::span_lint_and_then;
|
||||
use clippy_utils::source::snippet_opt;
|
||||
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: &[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(
|
||||
cx,
|
||||
DOC_COMMENT_DOUBLE_SPACE_LINEBREAK,
|
||||
lo_span.to(hi_span),
|
||||
"doc comment uses two spaces for a hard line break",
|
||||
|diag| {
|
||||
diag.multipart_suggestion(
|
||||
"replace this double space with a backslash",
|
||||
replacements,
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
fn collect_doc_replacements(cx: &LateContext<'_>, spans: &[Span]) -> Vec<(Span, String)> {
|
||||
spans
|
||||
.iter()
|
||||
.map(|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}");
|
||||
(*span, new_comment)
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
|
@ -7,6 +7,7 @@ use clippy_config::Conf;
|
|||
use clippy_utils::attrs::is_doc_hidden;
|
||||
use clippy_utils::diagnostics::{span_lint, span_lint_and_help, span_lint_and_then};
|
||||
use clippy_utils::macros::{is_panic, root_macro_call_first_node};
|
||||
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};
|
||||
|
|
@ -33,6 +34,7 @@ use rustc_span::{Span, sym};
|
|||
use std::ops::Range;
|
||||
use url::Url;
|
||||
|
||||
mod doc_comment_double_space_linebreak;
|
||||
mod include_in_doc_without_cfg;
|
||||
mod link_with_quotes;
|
||||
mod markdown;
|
||||
|
|
@ -567,6 +569,38 @@ declare_clippy_lint! {
|
|||
"link reference defined in list item or quote"
|
||||
}
|
||||
|
||||
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 formatting or manual refactoring. The use of a back-slash (`\`)
|
||||
/// is clearer in this regard.
|
||||
///
|
||||
/// ### Example
|
||||
/// The two replacement 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,
|
||||
pedantic,
|
||||
"double-space used for doc comment linebreak instead of `\\`"
|
||||
}
|
||||
|
||||
pub struct Documentation {
|
||||
valid_idents: FxHashSet<String>,
|
||||
check_private_items: bool,
|
||||
|
|
@ -598,6 +632,7 @@ impl_lint_pass!(Documentation => [
|
|||
DOC_OVERINDENTED_LIST_ITEMS,
|
||||
TOO_LONG_FIRST_DOC_PARAGRAPH,
|
||||
DOC_INCLUDE_WITHOUT_CFG,
|
||||
DOC_COMMENT_DOUBLE_SPACE_LINEBREAK
|
||||
]);
|
||||
|
||||
impl EarlyLintPass for Documentation {
|
||||
|
|
@ -737,6 +772,8 @@ fn check_attrs(cx: &LateContext<'_>, valid_idents: &FxHashSet<String>, attrs: &[
|
|||
return None;
|
||||
}
|
||||
|
||||
suspicious_doc_comments::check(cx, attrs);
|
||||
|
||||
let (fragments, _) = attrs_to_doc_fragments(
|
||||
attrs.iter().filter_map(|attr| {
|
||||
if attr.doc_str_and_comment_kind().is_none() || attr.span().in_external_macro(cx.sess().source_map()) {
|
||||
|
|
@ -894,6 +931,7 @@ fn check_doc<'a, Events: Iterator<Item = (pulldown_cmark::Event<'a>, Range<usize
|
|||
let mut paragraph_range = 0..0;
|
||||
let mut code_level = 0;
|
||||
let mut blockquote_level = 0;
|
||||
let mut collected_breaks: Vec<Span> = Vec::new();
|
||||
let mut is_first_paragraph = true;
|
||||
|
||||
let mut containers = Vec::new();
|
||||
|
|
@ -1069,6 +1107,14 @@ fn check_doc<'a, Events: Iterator<Item = (pulldown_cmark::Event<'a>, Range<usize
|
|||
&containers[..],
|
||||
);
|
||||
}
|
||||
|
||||
if let Some(span) = fragments.span(cx, range.clone())
|
||||
&& !span.from_expansion()
|
||||
&& let Some(snippet) = snippet_opt(cx, span)
|
||||
&& !snippet.trim().starts_with('\\')
|
||||
&& event == HardBreak {
|
||||
collected_breaks.push(span);
|
||||
}
|
||||
},
|
||||
Text(text) => {
|
||||
paragraph_range.end = range.end;
|
||||
|
|
@ -1119,6 +1165,9 @@ fn check_doc<'a, Events: Iterator<Item = (pulldown_cmark::Event<'a>, Range<usize
|
|||
FootnoteReference(_) => {}
|
||||
}
|
||||
}
|
||||
|
||||
doc_comment_double_space_linebreak::check(cx, &collected_breaks);
|
||||
|
||||
headers
|
||||
}
|
||||
|
||||
|
|
|
|||
94
tests/ui/doc/doc_comment_double_space_linebreak.fixed
Normal file
94
tests/ui/doc/doc_comment_double_space_linebreak.fixed
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
#![feature(custom_inner_attributes)]
|
||||
#![rustfmt::skip]
|
||||
|
||||
#![warn(clippy::doc_comment_double_space_linebreak)]
|
||||
#![allow(unused, clippy::empty_docs)]
|
||||
|
||||
//! 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
|
||||
|
||||
#[doc = "This is a doc attribute, which should not be linted"]
|
||||
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() {}
|
||||
|
||||
/// 🌹 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!();
|
||||
|
||||
// dont lint when its alone on a line
|
||||
///
|
||||
fn alone() {}
|
||||
|
||||
/// | First column | Second column |
|
||||
/// | ------------ | ------------- |
|
||||
/// | Not a line | break when |
|
||||
/// | after a line | in a table |
|
||||
fn table() {}
|
||||
|
||||
/// ```text
|
||||
/// It's also not a hard line break if
|
||||
/// there's two spaces at the end of a
|
||||
/// line in a block code.
|
||||
/// ```
|
||||
fn codeblock() {}
|
||||
|
||||
/// It's also not a hard line break `if
|
||||
/// there's` two spaces in the middle of inline code.
|
||||
fn inline() {}
|
||||
|
||||
/// It's also not a hard line break [when](
|
||||
/// 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() {}
|
||||
94
tests/ui/doc/doc_comment_double_space_linebreak.rs
Normal file
94
tests/ui/doc/doc_comment_double_space_linebreak.rs
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
#![feature(custom_inner_attributes)]
|
||||
#![rustfmt::skip]
|
||||
|
||||
#![warn(clippy::doc_comment_double_space_linebreak)]
|
||||
#![allow(unused, clippy::empty_docs)]
|
||||
|
||||
//! 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
|
||||
|
||||
#[doc = "This is a doc attribute, which should not be linted"]
|
||||
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() {}
|
||||
|
||||
/// 🌹 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!();
|
||||
|
||||
// dont lint when its alone on a line
|
||||
///
|
||||
fn alone() {}
|
||||
|
||||
/// | First column | Second column |
|
||||
/// | ------------ | ------------- |
|
||||
/// | Not a line | break when |
|
||||
/// | after a line | in a table |
|
||||
fn table() {}
|
||||
|
||||
/// ```text
|
||||
/// It's also not a hard line break if
|
||||
/// there's two spaces at the end of a
|
||||
/// line in a block code.
|
||||
/// ```
|
||||
fn codeblock() {}
|
||||
|
||||
/// It's also not a hard line break `if
|
||||
/// there's` two spaces in the middle of inline code.
|
||||
fn inline() {}
|
||||
|
||||
/// It's also not a hard line break [when](
|
||||
/// 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() {}
|
||||
76
tests/ui/doc/doc_comment_double_space_linebreak.stderr
Normal file
76
tests/ui/doc/doc_comment_double_space_linebreak.stderr
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
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
|
||||
| ___________________________________________^
|
||||
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 backslash
|
||||
|
|
||||
LL ~ //! Should warn on double space linebreaks\
|
||||
LL ~ //! in file/module doc comment
|
||||
|
|
||||
|
||||
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
|
||||
| ___________________________________________________^
|
||||
LL | | /// as a line-break, even when there are multiple
|
||||
LL | | /// in a row
|
||||
| |____^
|
||||
|
|
||||
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 comment uses two spaces for a hard line break
|
||||
--> tests/ui/doc/doc_comment_double_space_linebreak.rs:44:12
|
||||
|
|
||||
LL | /// 🌹 are 🟥
|
||||
| ______________^
|
||||
LL | | /// 🌷 are 🟦
|
||||
LL | | /// 📎 is 😎
|
||||
LL | | /// and so are 🫵
|
||||
LL | | /// (hopefully no formatting weirdness linting this)
|
||||
| |____^
|
||||
|
|
||||
help: replace this double space with a backslash
|
||||
|
|
||||
LL ~ /// 🌹 are 🟥\
|
||||
LL ~ /// 🌷 are 🟦\
|
||||
LL ~ /// 📎 is 😎\
|
||||
LL ~ /// and so are 🫵\
|
||||
LL ~ /// (hopefully no formatting weirdness linting this)
|
||||
|
|
||||
|
||||
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
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue