config instead of new lint and don't panic

This commit is contained in:
Centri3 2023-04-19 21:46:13 -05:00
parent fa1efa8b10
commit a3aeec4f75
16 changed files with 468 additions and 98 deletions

View File

@ -4884,7 +4884,6 @@ Released 2018-09-13
[`semicolon_if_nothing_returned`]: https://rust-lang.github.io/rust-clippy/master/index.html#semicolon_if_nothing_returned
[`semicolon_inside_block`]: https://rust-lang.github.io/rust-clippy/master/index.html#semicolon_inside_block
[`semicolon_outside_block`]: https://rust-lang.github.io/rust-clippy/master/index.html#semicolon_outside_block
[`semicolon_outside_block_if_singleline`]: https://rust-lang.github.io/rust-clippy/master/index.html#semicolon_outside_block_if_singleline
[`separated_literal_suffix`]: https://rust-lang.github.io/rust-clippy/master/index.html#separated_literal_suffix
[`serde_api_misuse`]: https://rust-lang.github.io/rust-clippy/master/index.html#serde_api_misuse
[`shadow_reuse`]: https://rust-lang.github.io/rust-clippy/master/index.html#shadow_reuse

View File

@ -546,7 +546,6 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[
crate::self_named_constructors::SELF_NAMED_CONSTRUCTORS_INFO,
crate::semicolon_block::SEMICOLON_INSIDE_BLOCK_INFO,
crate::semicolon_block::SEMICOLON_OUTSIDE_BLOCK_INFO,
crate::semicolon_block::SEMICOLON_OUTSIDE_BLOCK_IF_SINGLELINE_INFO,
crate::semicolon_if_nothing_returned::SEMICOLON_IF_NOTHING_RETURNED_INFO,
crate::serde_api::SERDE_API_MISUSE_INFO,
crate::shadow::SHADOW_REUSE_INFO,

View File

@ -932,7 +932,14 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
store.register_late_pass(|_| Box::new(from_raw_with_void_ptr::FromRawWithVoidPtr));
store.register_late_pass(|_| Box::new(suspicious_xor_used_as_pow::ConfusingXorAndPow));
store.register_late_pass(move |_| Box::new(manual_is_ascii_check::ManualIsAsciiCheck::new(msrv())));
store.register_late_pass(|_| Box::new(semicolon_block::SemicolonBlock));
let semicolon_inside_block_if_multiline = conf.semicolon_inside_block_if_multiline;
let semicolon_outside_block_if_singleline = conf.semicolon_outside_block_if_singleline;
store.register_late_pass(move |_| {
Box::new(semicolon_block::SemicolonBlock::new(
semicolon_inside_block_if_multiline,
semicolon_outside_block_if_singleline,
))
});
store.register_late_pass(|_| Box::new(fn_null_check::FnNullCheck));
store.register_late_pass(|_| Box::new(permissions_set_readonly_false::PermissionsSetReadonlyFalse));
store.register_late_pass(|_| Box::new(size_of_ref::SizeOfRef));

View File

@ -2,7 +2,7 @@ use clippy_utils::diagnostics::{multispan_sugg_with_applicability, span_lint_and
use rustc_errors::Applicability;
use rustc_hir::{Block, Expr, ExprKind, Stmt, StmtKind};
use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_session::{declare_tool_lint, impl_lint_pass};
use rustc_span::Span;
declare_clippy_lint! {
@ -64,49 +64,22 @@ declare_clippy_lint! {
restriction,
"add a semicolon outside the block"
}
declare_clippy_lint! {
/// ### What it does
///
/// Suggests moving the semicolon from a block's final expression outside of
/// the block if it's singleline, and inside the block if it's multiline.
///
/// ### Why is this bad?
///
/// Some may prefer if the semicolon is outside of a block if it is only one
/// expression, as this allows rustfmt to make it singleline (and may just be
/// more readable). In the case that it isn't, it should be inside.
/// Take a look at both `semicolon_inside_block` and `semicolon_outside_block`
/// for alternatives.
///
/// ### Example
///
/// ```rust
/// # fn f(_: u32) {}
/// # let x = 0;
/// unsafe { f(x); }
///
/// unsafe {
/// let x = 1;
/// f(x)
/// };
/// ```
/// Use instead:
/// ```rust
/// # fn f(_: u32) {}
/// # let x = 0;
/// unsafe { f(x) };
///
/// unsafe {
/// let x = 1;
/// f(x);
/// }
/// ```
#[clippy::version = "1.68.0"]
pub SEMICOLON_OUTSIDE_BLOCK_IF_SINGLELINE,
restriction,
"add a semicolon inside the block if it's singleline, otherwise outside"
impl_lint_pass!(SemicolonBlock => [SEMICOLON_INSIDE_BLOCK, SEMICOLON_OUTSIDE_BLOCK]);
#[derive(Copy, Clone)]
pub struct SemicolonBlock {
semicolon_inside_block_if_multiline: bool,
semicolon_outside_block_if_singleline: bool,
}
impl SemicolonBlock {
pub fn new(semicolon_inside_block_if_multiline: bool, semicolon_outside_block_if_singleline: bool) -> Self {
Self {
semicolon_inside_block_if_multiline,
semicolon_outside_block_if_singleline,
}
}
}
declare_lint_pass!(SemicolonBlock => [SEMICOLON_INSIDE_BLOCK, SEMICOLON_OUTSIDE_BLOCK, SEMICOLON_OUTSIDE_BLOCK_IF_SINGLELINE]);
impl LateLintPass<'_> for SemicolonBlock {
fn check_stmt(&mut self, cx: &LateContext<'_>, stmt: &Stmt<'_>) {
@ -125,24 +98,34 @@ impl LateLintPass<'_> for SemicolonBlock {
span,
..
} = stmt else { return };
semicolon_outside_block(cx, block, expr, span);
semicolon_outside_block(self, cx, block, expr, span);
},
StmtKind::Semi(Expr {
kind: ExprKind::Block(block @ Block { expr: Some(tail), .. }, _),
..
}) if !block.span.from_expansion() => {
semicolon_inside_block(cx, block, tail, stmt.span);
semicolon_inside_block(self, cx, block, tail, stmt.span);
},
_ => (),
}
}
}
fn semicolon_inside_block(cx: &LateContext<'_>, block: &Block<'_>, tail: &Expr<'_>, semi_span: Span) {
fn semicolon_inside_block(
conf: &mut SemicolonBlock,
cx: &LateContext<'_>,
block: &Block<'_>,
tail: &Expr<'_>,
semi_span: Span,
) {
let insert_span = tail.span.source_callsite().shrink_to_hi();
let remove_span = semi_span.with_lo(block.span.hi());
semicolon_outside_block_if_singleline(cx, block, remove_span, insert_span, true, "inside");
if conf.semicolon_inside_block_if_multiline {
if get_line(cx, remove_span) == get_line(cx, insert_span) {
return;
}
}
span_lint_and_then(
cx,
@ -160,13 +143,17 @@ fn semicolon_inside_block(cx: &LateContext<'_>, block: &Block<'_>, tail: &Expr<'
);
}
fn semicolon_outside_block(cx: &LateContext<'_>, block: &Block<'_>, tail_stmt_expr: &Expr<'_>, semi_span: Span) {
fn semicolon_outside_block(conf: &mut SemicolonBlock, cx: &LateContext<'_>, block: &Block<'_>, tail_stmt_expr: &Expr<'_>, semi_span: Span) {
let insert_span = block.span.with_lo(block.span.hi());
// account for macro calls
let semi_span = cx.sess().source_map().stmt_span(semi_span, block.span);
let remove_span = semi_span.with_lo(tail_stmt_expr.span.source_callsite().hi());
semicolon_outside_block_if_singleline(cx, block, remove_span, insert_span, false, "outside");
if conf.semicolon_outside_block_if_singleline {
if get_line(cx, remove_span) != get_line(cx, insert_span) {
return;
}
}
span_lint_and_then(
cx,
@ -184,44 +171,10 @@ fn semicolon_outside_block(cx: &LateContext<'_>, block: &Block<'_>, tail_stmt_ex
);
}
fn semicolon_outside_block_if_singleline(
cx: &LateContext<'_>,
block: &Block<'_>,
remove_span: Span,
insert_span: Span,
inequality: bool,
ty: &str,
) {
let (remove_line, insert_line) = (get_line(cx, remove_span), get_line(cx, insert_span));
let eq = if inequality {
remove_line != insert_line
} else {
remove_line == insert_line
};
if eq {
span_lint_and_then(
cx,
SEMICOLON_OUTSIDE_BLOCK_IF_SINGLELINE,
block.span,
&format!("consider moving the `;` {ty} the block for consistent formatting"),
|diag| {
multispan_sugg_with_applicability(
diag,
"put the `;` here",
Applicability::MachineApplicable,
[(remove_span, String::new()), (insert_span, ";".to_owned())],
);
},
);
fn get_line(cx: &LateContext<'_>, span: Span) -> Option<usize> {
if let Ok(line) = cx.sess().source_map().lookup_line(span.lo()) {
return Some(line.line);
}
}
fn get_line(cx: &LateContext<'_>, span: Span) -> usize {
cx.sess()
.source_map()
.lookup_line(span.lo())
.expect("failed to get span's line")
.line
None
}

View File

@ -463,6 +463,14 @@ define_Conf! {
///
/// The maximum byte size a `Future` can have, before it triggers the `clippy::large_futures` lint
(future_size_threshold: u64 = 16 * 1024),
/// Lint: SEMICOLON_INSIDE_BLOCK.
///
/// Whether to lint only if it's multiline.
(semicolon_inside_block_if_multiline: bool = false),
/// Lint: SEMICOLON_OUTSIDE_BLOCK.
///
/// Whether to lint only if it's singleline.
(semicolon_outside_block_if_singleline: bool = false),
}
/// Search for the configuration file.

View File

@ -6,7 +6,8 @@
clippy::no_effect,
clippy::single_element_loop
)]
#![warn(clippy::semicolon_outside_block_if_singleline)]
#![warn(clippy::semicolon_inside_block)]
#![warn(clippy::semicolon_outside_block)]
macro_rules! m {
(()) => {

View File

@ -0,0 +1,86 @@
// run-rustfix
#![allow(
unused,
clippy::unused_unit,
clippy::unnecessary_operation,
clippy::no_effect,
clippy::single_element_loop
)]
#![warn(clippy::semicolon_inside_block)]
#![warn(clippy::semicolon_outside_block)]
macro_rules! m {
(()) => {
()
};
(0) => {{
0
};};
(1) => {{
1;
}};
(2) => {{
2;
}};
}
fn unit_fn_block() {
()
}
#[rustfmt::skip]
fn main() {
{ unit_fn_block() }
unsafe { unit_fn_block() }
{
unit_fn_block()
}
{ unit_fn_block() };
unsafe { unit_fn_block() };
{ unit_fn_block(); }
unsafe { unit_fn_block(); }
{ unit_fn_block(); };
unsafe { unit_fn_block(); };
{
unit_fn_block();
unit_fn_block()
};
{
unit_fn_block();
unit_fn_block();
}
{
unit_fn_block();
unit_fn_block();
};
{ m!(()) };
{ m!(()); }
{ m!(()); };
m!(0);
m!(1);
m!(2);
for _ in [()] {
unit_fn_block();
}
for _ in [()] {
unit_fn_block()
}
let _d = || {
unit_fn_block();
};
let _d = || {
unit_fn_block()
};
{ unit_fn_block(); };
unit_fn_block()
}

View File

@ -1,10 +1,10 @@
error: consider moving the `;` outside the block for consistent formatting
--> $DIR/semicolon_outside_block_if_singleline.rs:42:5
--> $DIR/both.rs:43:5
|
LL | { unit_fn_block(); }
| ^^^^^^^^^^^^^^^^^^^^
|
= note: `-D clippy::semicolon-outside-block-if-singleline` implied by `-D warnings`
= note: `-D clippy::semicolon-outside-block` implied by `-D warnings`
help: put the `;` here
|
LL - { unit_fn_block(); }
@ -12,7 +12,7 @@ LL + { unit_fn_block() };
|
error: consider moving the `;` outside the block for consistent formatting
--> $DIR/semicolon_outside_block_if_singleline.rs:43:5
--> $DIR/both.rs:44:5
|
LL | unsafe { unit_fn_block(); }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -24,14 +24,15 @@ LL + unsafe { unit_fn_block() };
|
error: consider moving the `;` inside the block for consistent formatting
--> $DIR/semicolon_outside_block_if_singleline.rs:48:5
--> $DIR/both.rs:49:5
|
LL | / {
LL | | unit_fn_block();
LL | | unit_fn_block()
LL | | };
| |_____^
| |______^
|
= note: `-D clippy::semicolon-inside-block` implied by `-D warnings`
help: put the `;` here
|
LL ~ unit_fn_block();
@ -39,7 +40,7 @@ LL ~ }
|
error: consider moving the `;` outside the block for consistent formatting
--> $DIR/semicolon_outside_block_if_singleline.rs:62:5
--> $DIR/both.rs:63:5
|
LL | { m!(()); }
| ^^^^^^^^^^^

View File

@ -0,0 +1,2 @@
semicolon-inside-block-if-multiline = true
semicolon-outside-block-if-singleline = true

View File

@ -0,0 +1,85 @@
// run-rustfix
#![allow(
unused,
clippy::unused_unit,
clippy::unnecessary_operation,
clippy::no_effect,
clippy::single_element_loop
)]
#![warn(clippy::semicolon_inside_block)]
macro_rules! m {
(()) => {
()
};
(0) => {{
0
};};
(1) => {{
1;
}};
(2) => {{
2;
}};
}
fn unit_fn_block() {
()
}
#[rustfmt::skip]
fn main() {
{ unit_fn_block() }
unsafe { unit_fn_block() }
{
unit_fn_block()
}
{ unit_fn_block() };
unsafe { unit_fn_block() };
{ unit_fn_block(); }
unsafe { unit_fn_block(); }
{ unit_fn_block(); };
unsafe { unit_fn_block(); };
{
unit_fn_block();
unit_fn_block();
}
{
unit_fn_block();
unit_fn_block();
}
{
unit_fn_block();
unit_fn_block();
};
{ m!(()) };
{ m!(()); }
{ m!(()); };
m!(0);
m!(1);
m!(2);
for _ in [()] {
unit_fn_block();
}
for _ in [()] {
unit_fn_block()
}
let _d = || {
unit_fn_block();
};
let _d = || {
unit_fn_block()
};
{ unit_fn_block(); };
unit_fn_block()
}

View File

@ -6,7 +6,7 @@
clippy::no_effect,
clippy::single_element_loop
)]
#![warn(clippy::semicolon_outside_block_if_singleline)]
#![warn(clippy::semicolon_inside_block)]
macro_rules! m {
(()) => {

View File

@ -0,0 +1,18 @@
error: consider moving the `;` inside the block for consistent formatting
--> $DIR/semicolon_inside_block.rs:48:5
|
LL | / {
LL | | unit_fn_block();
LL | | unit_fn_block()
LL | | };
| |______^
|
= note: `-D clippy::semicolon-inside-block` implied by `-D warnings`
help: put the `;` here
|
LL ~ unit_fn_block();
LL ~ }
|
error: aborting due to previous error

View File

@ -0,0 +1,85 @@
// run-rustfix
#![allow(
unused,
clippy::unused_unit,
clippy::unnecessary_operation,
clippy::no_effect,
clippy::single_element_loop
)]
#![warn(clippy::semicolon_outside_block)]
macro_rules! m {
(()) => {
()
};
(0) => {{
0
};};
(1) => {{
1;
}};
(2) => {{
2;
}};
}
fn unit_fn_block() {
()
}
#[rustfmt::skip]
fn main() {
{ unit_fn_block() }
unsafe { unit_fn_block() }
{
unit_fn_block()
}
{ unit_fn_block() };
unsafe { unit_fn_block() };
{ unit_fn_block() };
unsafe { unit_fn_block() };
{ unit_fn_block(); };
unsafe { unit_fn_block(); };
{
unit_fn_block();
unit_fn_block()
};
{
unit_fn_block();
unit_fn_block();
}
{
unit_fn_block();
unit_fn_block();
};
{ m!(()) };
{ m!(()) };
{ m!(()); };
m!(0);
m!(1);
m!(2);
for _ in [()] {
unit_fn_block();
}
for _ in [()] {
unit_fn_block()
}
let _d = || {
unit_fn_block();
};
let _d = || {
unit_fn_block()
};
{ unit_fn_block(); };
unit_fn_block()
}

View File

@ -0,0 +1,85 @@
// run-rustfix
#![allow(
unused,
clippy::unused_unit,
clippy::unnecessary_operation,
clippy::no_effect,
clippy::single_element_loop
)]
#![warn(clippy::semicolon_outside_block)]
macro_rules! m {
(()) => {
()
};
(0) => {{
0
};};
(1) => {{
1;
}};
(2) => {{
2;
}};
}
fn unit_fn_block() {
()
}
#[rustfmt::skip]
fn main() {
{ unit_fn_block() }
unsafe { unit_fn_block() }
{
unit_fn_block()
}
{ unit_fn_block() };
unsafe { unit_fn_block() };
{ unit_fn_block(); }
unsafe { unit_fn_block(); }
{ unit_fn_block(); };
unsafe { unit_fn_block(); };
{
unit_fn_block();
unit_fn_block()
};
{
unit_fn_block();
unit_fn_block();
}
{
unit_fn_block();
unit_fn_block();
};
{ m!(()) };
{ m!(()); }
{ m!(()); };
m!(0);
m!(1);
m!(2);
for _ in [()] {
unit_fn_block();
}
for _ in [()] {
unit_fn_block()
}
let _d = || {
unit_fn_block();
};
let _d = || {
unit_fn_block()
};
{ unit_fn_block(); };
unit_fn_block()
}

View File

@ -0,0 +1,39 @@
error: consider moving the `;` outside the block for consistent formatting
--> $DIR/semicolon_outside_block.rs:42:5
|
LL | { unit_fn_block(); }
| ^^^^^^^^^^^^^^^^^^^^
|
= note: `-D clippy::semicolon-outside-block` implied by `-D warnings`
help: put the `;` here
|
LL - { unit_fn_block(); }
LL + { unit_fn_block() };
|
error: consider moving the `;` outside the block for consistent formatting
--> $DIR/semicolon_outside_block.rs:43:5
|
LL | unsafe { unit_fn_block(); }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: put the `;` here
|
LL - unsafe { unit_fn_block(); }
LL + unsafe { unit_fn_block() };
|
error: consider moving the `;` outside the block for consistent formatting
--> $DIR/semicolon_outside_block.rs:62:5
|
LL | { m!(()); }
| ^^^^^^^^^^^
|
help: put the `;` here
|
LL - { m!(()); }
LL + { m!(()) };
|
error: aborting due to 3 previous errors

View File

@ -37,6 +37,8 @@ error: error reading Clippy's configuration file `$DIR/clippy.toml`: unknown fie
missing-docs-in-crate-items
msrv
pass-by-value-size-limit
semicolon-inside-block-if-multiline
semicolon-outside-block-if-singleline
single-char-binding-names-threshold
standard-macro-braces
suppress-restriction-lint-in-const