New lint [four_forward_slashes
]
Make it trim the contents
This commit is contained in:
parent
d398e59163
commit
885ce610fe
@ -4867,6 +4867,7 @@ Released 2018-09-13
|
|||||||
[`forget_ref`]: https://rust-lang.github.io/rust-clippy/master/index.html#forget_ref
|
[`forget_ref`]: https://rust-lang.github.io/rust-clippy/master/index.html#forget_ref
|
||||||
[`format_in_format_args`]: https://rust-lang.github.io/rust-clippy/master/index.html#format_in_format_args
|
[`format_in_format_args`]: https://rust-lang.github.io/rust-clippy/master/index.html#format_in_format_args
|
||||||
[`format_push_string`]: https://rust-lang.github.io/rust-clippy/master/index.html#format_push_string
|
[`format_push_string`]: https://rust-lang.github.io/rust-clippy/master/index.html#format_push_string
|
||||||
|
[`four_forward_slashes`]: https://rust-lang.github.io/rust-clippy/master/index.html#four_forward_slashes
|
||||||
[`from_iter_instead_of_collect`]: https://rust-lang.github.io/rust-clippy/master/index.html#from_iter_instead_of_collect
|
[`from_iter_instead_of_collect`]: https://rust-lang.github.io/rust-clippy/master/index.html#from_iter_instead_of_collect
|
||||||
[`from_over_into`]: https://rust-lang.github.io/rust-clippy/master/index.html#from_over_into
|
[`from_over_into`]: https://rust-lang.github.io/rust-clippy/master/index.html#from_over_into
|
||||||
[`from_raw_with_void_ptr`]: https://rust-lang.github.io/rust-clippy/master/index.html#from_raw_with_void_ptr
|
[`from_raw_with_void_ptr`]: https://rust-lang.github.io/rust-clippy/master/index.html#from_raw_with_void_ptr
|
||||||
|
@ -184,6 +184,7 @@
|
|||||||
crate::formatting::SUSPICIOUS_ASSIGNMENT_FORMATTING_INFO,
|
crate::formatting::SUSPICIOUS_ASSIGNMENT_FORMATTING_INFO,
|
||||||
crate::formatting::SUSPICIOUS_ELSE_FORMATTING_INFO,
|
crate::formatting::SUSPICIOUS_ELSE_FORMATTING_INFO,
|
||||||
crate::formatting::SUSPICIOUS_UNARY_OP_FORMATTING_INFO,
|
crate::formatting::SUSPICIOUS_UNARY_OP_FORMATTING_INFO,
|
||||||
|
crate::four_forward_slashes::FOUR_FORWARD_SLASHES_INFO,
|
||||||
crate::from_over_into::FROM_OVER_INTO_INFO,
|
crate::from_over_into::FROM_OVER_INTO_INFO,
|
||||||
crate::from_raw_with_void_ptr::FROM_RAW_WITH_VOID_PTR_INFO,
|
crate::from_raw_with_void_ptr::FROM_RAW_WITH_VOID_PTR_INFO,
|
||||||
crate::from_str_radix_10::FROM_STR_RADIX_10_INFO,
|
crate::from_str_radix_10::FROM_STR_RADIX_10_INFO,
|
||||||
|
82
clippy_lints/src/four_forward_slashes.rs
Normal file
82
clippy_lints/src/four_forward_slashes.rs
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
use clippy_utils::{diagnostics::span_lint_and_sugg, source::snippet_opt};
|
||||||
|
use rustc_errors::Applicability;
|
||||||
|
use rustc_hir::Item;
|
||||||
|
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
||||||
|
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||||
|
use rustc_span::{Span, SyntaxContext};
|
||||||
|
|
||||||
|
declare_clippy_lint! {
|
||||||
|
/// ### What it does
|
||||||
|
/// Checks for outer doc comments written with 4 forward slashes (`////`).
|
||||||
|
///
|
||||||
|
/// ### Why is this bad?
|
||||||
|
/// This is (probably) a typo, and results in it not being a doc comment; just a regular
|
||||||
|
/// comment.
|
||||||
|
///
|
||||||
|
/// ### Example
|
||||||
|
/// ```rust
|
||||||
|
/// //// My amazing data structure
|
||||||
|
/// pub struct Foo {
|
||||||
|
/// // ...
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// Use instead:
|
||||||
|
/// ```rust
|
||||||
|
/// /// My amazing data structure
|
||||||
|
/// pub struct Foo {
|
||||||
|
/// // ...
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
#[clippy::version = "1.72.0"]
|
||||||
|
pub FOUR_FORWARD_SLASHES,
|
||||||
|
suspicious,
|
||||||
|
"comments with 4 forward slashes (`////`) likely intended to be doc comments (`///`)"
|
||||||
|
}
|
||||||
|
declare_lint_pass!(FourForwardSlashes => [FOUR_FORWARD_SLASHES]);
|
||||||
|
|
||||||
|
impl<'tcx> LateLintPass<'tcx> for FourForwardSlashes {
|
||||||
|
fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {
|
||||||
|
if item.span.from_expansion() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let src = cx.sess().source_map();
|
||||||
|
let item_and_attrs_span = cx
|
||||||
|
.tcx
|
||||||
|
.hir()
|
||||||
|
.attrs(item.hir_id())
|
||||||
|
.iter()
|
||||||
|
.fold(item.span.shrink_to_lo(), |span, attr| span.to(attr.span));
|
||||||
|
let (Some(file), _, _, end_line, _) = src.span_to_location_info(item_and_attrs_span) else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
for line in (0..end_line.saturating_sub(1)).rev() {
|
||||||
|
let Some(contents) = file.get_line(line) else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
let contents = contents.trim();
|
||||||
|
if contents.is_empty() {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if contents.starts_with("////") {
|
||||||
|
let bounds = file.line_bounds(line);
|
||||||
|
let span = Span::new(bounds.start, bounds.end, SyntaxContext::root(), None);
|
||||||
|
|
||||||
|
if snippet_opt(cx, span).is_some_and(|s| s.trim().starts_with("////")) {
|
||||||
|
span_lint_and_sugg(
|
||||||
|
cx,
|
||||||
|
FOUR_FORWARD_SLASHES,
|
||||||
|
span,
|
||||||
|
"comment with 4 forward slashes (`////`). This looks like a doc comment, but it isn't",
|
||||||
|
"make this a doc comment by removing one `/`",
|
||||||
|
// It's a little unfortunate but the span includes the `\n` yet the contents
|
||||||
|
// do not, so we must add it back. If some codebase uses `\r\n` instead they
|
||||||
|
// will need normalization but it should be fine
|
||||||
|
contents.replacen("////", "///", 1) + "\n",
|
||||||
|
Applicability::MachineApplicable,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -137,6 +137,7 @@
|
|||||||
mod format_impl;
|
mod format_impl;
|
||||||
mod format_push_string;
|
mod format_push_string;
|
||||||
mod formatting;
|
mod formatting;
|
||||||
|
mod four_forward_slashes;
|
||||||
mod from_over_into;
|
mod from_over_into;
|
||||||
mod from_raw_with_void_ptr;
|
mod from_raw_with_void_ptr;
|
||||||
mod from_str_radix_10;
|
mod from_str_radix_10;
|
||||||
@ -1081,6 +1082,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
|
|||||||
store.register_early_pass(|| Box::new(visibility::Visibility));
|
store.register_early_pass(|| Box::new(visibility::Visibility));
|
||||||
store.register_late_pass(move |_| Box::new(tuple_array_conversions::TupleArrayConversions { msrv: msrv() }));
|
store.register_late_pass(move |_| Box::new(tuple_array_conversions::TupleArrayConversions { msrv: msrv() }));
|
||||||
store.register_late_pass(|_| Box::new(manual_float_methods::ManualFloatMethods));
|
store.register_late_pass(|_| Box::new(manual_float_methods::ManualFloatMethods));
|
||||||
|
store.register_late_pass(|_| Box::new(four_forward_slashes::FourForwardSlashes));
|
||||||
// add lints here, do not remove this comment, it's used in `new_lint`
|
// add lints here, do not remove this comment, it's used in `new_lint`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
44
tests/ui/four_forward_slashes.fixed
Normal file
44
tests/ui/four_forward_slashes.fixed
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
//// first line borked doc comment. doesn't combust!
|
||||||
|
//@run-rustfix
|
||||||
|
//@aux-build:proc_macros.rs:proc-macro
|
||||||
|
#![feature(custom_inner_attributes)]
|
||||||
|
#![allow(unused)]
|
||||||
|
#![warn(clippy::four_forward_slashes)]
|
||||||
|
#![no_main]
|
||||||
|
#![rustfmt::skip]
|
||||||
|
|
||||||
|
#[macro_use]
|
||||||
|
extern crate proc_macros;
|
||||||
|
|
||||||
|
/// whoops
|
||||||
|
fn a() {}
|
||||||
|
|
||||||
|
/// whoops
|
||||||
|
#[allow(dead_code)]
|
||||||
|
fn b() {}
|
||||||
|
|
||||||
|
/// whoops
|
||||||
|
/// two borked comments!
|
||||||
|
#[track_caller]
|
||||||
|
fn c() {}
|
||||||
|
|
||||||
|
fn d() {}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
/// between attributes
|
||||||
|
#[allow(dead_code)]
|
||||||
|
fn g() {}
|
||||||
|
|
||||||
|
/// not very start of contents
|
||||||
|
fn h() {}
|
||||||
|
|
||||||
|
external! {
|
||||||
|
//// don't lint me bozo
|
||||||
|
fn e() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
with_span! {
|
||||||
|
span
|
||||||
|
//// don't lint me bozo
|
||||||
|
fn f() {}
|
||||||
|
}
|
44
tests/ui/four_forward_slashes.rs
Normal file
44
tests/ui/four_forward_slashes.rs
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
//// first line borked doc comment. doesn't combust!
|
||||||
|
//@run-rustfix
|
||||||
|
//@aux-build:proc_macros.rs:proc-macro
|
||||||
|
#![feature(custom_inner_attributes)]
|
||||||
|
#![allow(unused)]
|
||||||
|
#![warn(clippy::four_forward_slashes)]
|
||||||
|
#![no_main]
|
||||||
|
#![rustfmt::skip]
|
||||||
|
|
||||||
|
#[macro_use]
|
||||||
|
extern crate proc_macros;
|
||||||
|
|
||||||
|
//// whoops
|
||||||
|
fn a() {}
|
||||||
|
|
||||||
|
//// whoops
|
||||||
|
#[allow(dead_code)]
|
||||||
|
fn b() {}
|
||||||
|
|
||||||
|
//// whoops
|
||||||
|
//// two borked comments!
|
||||||
|
#[track_caller]
|
||||||
|
fn c() {}
|
||||||
|
|
||||||
|
fn d() {}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
//// between attributes
|
||||||
|
#[allow(dead_code)]
|
||||||
|
fn g() {}
|
||||||
|
|
||||||
|
//// not very start of contents
|
||||||
|
fn h() {}
|
||||||
|
|
||||||
|
external! {
|
||||||
|
//// don't lint me bozo
|
||||||
|
fn e() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
with_span! {
|
||||||
|
span
|
||||||
|
//// don't lint me bozo
|
||||||
|
fn f() {}
|
||||||
|
}
|
75
tests/ui/four_forward_slashes.stderr
Normal file
75
tests/ui/four_forward_slashes.stderr
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
error: comment with 4 forward slashes (`////`). This looks like a doc comment, but it isn't
|
||||||
|
--> $DIR/four_forward_slashes.rs:13:1
|
||||||
|
|
|
||||||
|
LL | / //// whoops
|
||||||
|
LL | | fn a() {}
|
||||||
|
| |_
|
||||||
|
|
|
||||||
|
= note: `-D clippy::four-forward-slashes` implied by `-D warnings`
|
||||||
|
help: make this a doc comment by removing one `/`
|
||||||
|
|
|
||||||
|
LL + /// whoops
|
||||||
|
|
|
||||||
|
|
||||||
|
error: comment with 4 forward slashes (`////`). This looks like a doc comment, but it isn't
|
||||||
|
--> $DIR/four_forward_slashes.rs:16:1
|
||||||
|
|
|
||||||
|
LL | / //// whoops
|
||||||
|
LL | | #[allow(dead_code)]
|
||||||
|
| |_
|
||||||
|
|
|
||||||
|
help: make this a doc comment by removing one `/`
|
||||||
|
|
|
||||||
|
LL + /// whoops
|
||||||
|
|
|
||||||
|
|
||||||
|
error: comment with 4 forward slashes (`////`). This looks like a doc comment, but it isn't
|
||||||
|
--> $DIR/four_forward_slashes.rs:21:1
|
||||||
|
|
|
||||||
|
LL | / //// two borked comments!
|
||||||
|
LL | | #[track_caller]
|
||||||
|
| |_
|
||||||
|
|
|
||||||
|
help: make this a doc comment by removing one `/`
|
||||||
|
|
|
||||||
|
LL + /// two borked comments!
|
||||||
|
|
|
||||||
|
|
||||||
|
error: comment with 4 forward slashes (`////`). This looks like a doc comment, but it isn't
|
||||||
|
--> $DIR/four_forward_slashes.rs:20:1
|
||||||
|
|
|
||||||
|
LL | / //// whoops
|
||||||
|
LL | | //// two borked comments!
|
||||||
|
| |_
|
||||||
|
|
|
||||||
|
help: make this a doc comment by removing one `/`
|
||||||
|
|
|
||||||
|
LL + /// whoops
|
||||||
|
|
|
||||||
|
|
||||||
|
error: comment with 4 forward slashes (`////`). This looks like a doc comment, but it isn't
|
||||||
|
--> $DIR/four_forward_slashes.rs:28:1
|
||||||
|
|
|
||||||
|
LL | / //// between attributes
|
||||||
|
LL | | #[allow(dead_code)]
|
||||||
|
| |_
|
||||||
|
|
|
||||||
|
help: make this a doc comment by removing one `/`
|
||||||
|
|
|
||||||
|
LL + /// between attributes
|
||||||
|
|
|
||||||
|
|
||||||
|
error: comment with 4 forward slashes (`////`). This looks like a doc comment, but it isn't
|
||||||
|
--> $DIR/four_forward_slashes.rs:32:1
|
||||||
|
|
|
||||||
|
LL | / //// not very start of contents
|
||||||
|
LL | | fn h() {}
|
||||||
|
| |_
|
||||||
|
|
|
||||||
|
help: make this a doc comment by removing one `/`
|
||||||
|
|
|
||||||
|
LL + /// not very start of contents
|
||||||
|
|
|
||||||
|
|
||||||
|
error: aborting due to 6 previous errors
|
||||||
|
|
Loading…
Reference in New Issue
Block a user