From 0a81f8257e2317b019406c42575d10bbd33c7268 Mon Sep 17 00:00:00 2001 From: Centri3 <114838443+Centri3@users.noreply.github.com> Date: Sun, 16 Apr 2023 23:30:00 -0500 Subject: [PATCH 01/11] add `semicolon_outside_block_if_singleline` lint --- CHANGELOG.md | 1 + clippy_lints/src/declared_lints.rs | 1 + clippy_lints/src/semicolon_block.rs | 92 ++++++++++++++++++- ...emicolon_outside_block_if_singleline.fixed | 85 +++++++++++++++++ .../semicolon_outside_block_if_singleline.rs | 85 +++++++++++++++++ ...micolon_outside_block_if_singleline.stderr | 54 +++++++++++ 6 files changed, 317 insertions(+), 1 deletion(-) create mode 100644 tests/ui/semicolon_outside_block_if_singleline.fixed create mode 100644 tests/ui/semicolon_outside_block_if_singleline.rs create mode 100644 tests/ui/semicolon_outside_block_if_singleline.stderr diff --git a/CHANGELOG.md b/CHANGELOG.md index 559b560dde4b..a0a7780f4c27 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4884,6 +4884,7 @@ 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 diff --git a/clippy_lints/src/declared_lints.rs b/clippy_lints/src/declared_lints.rs index f24dab627809..70379b6caf11 100644 --- a/clippy_lints/src/declared_lints.rs +++ b/clippy_lints/src/declared_lints.rs @@ -546,6 +546,7 @@ 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, diff --git a/clippy_lints/src/semicolon_block.rs b/clippy_lints/src/semicolon_block.rs index 34a3e5ddf4f6..d791100b9b9a 100644 --- a/clippy_lints/src/semicolon_block.rs +++ b/clippy_lints/src/semicolon_block.rs @@ -64,7 +64,48 @@ declare_clippy_lint! { restriction, "add a semicolon outside the block" } -declare_lint_pass!(SemicolonBlock => [SEMICOLON_INSIDE_BLOCK, SEMICOLON_OUTSIDE_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 if a block is only one + /// expression, as this allows rustfmt to make it singleline. 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" +} +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<'_>) { @@ -98,6 +139,8 @@ fn semicolon_inside_block(cx: &LateContext<'_>, block: &Block<'_>, tail: &Expr<' let insert_span = tail.span.source_callsite().shrink_to_hi(); let remove_span = semi_span.with_lo(block.span.hi()); + check_semicolon_outside_block_if_singleline(cx, block, remove_span, insert_span, true, "inside"); + span_lint_and_then( cx, SEMICOLON_INSIDE_BLOCK, @@ -120,6 +163,8 @@ fn semicolon_outside_block(cx: &LateContext<'_>, block: &Block<'_>, tail_stmt_ex 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()); + check_semicolon_outside_block_if_singleline(cx, block, remove_span, insert_span, false, "outside"); + span_lint_and_then( cx, SEMICOLON_OUTSIDE_BLOCK, @@ -135,3 +180,48 @@ fn semicolon_outside_block(cx: &LateContext<'_>, block: &Block<'_>, tail_stmt_ex }, ); } + +fn check_semicolon_outside_block_if_singleline( + cx: &LateContext<'_>, + block: &Block<'_>, + remove_span: Span, + insert_span: Span, + inequality: bool, + ty: &str, +) { + let remove_line = cx + .sess() + .source_map() + .lookup_line(remove_span.lo()) + .expect("failed to get `remove_span`'s line") + .line; + let insert_line = cx + .sess() + .source_map() + .lookup_line(insert_span.lo()) + .expect("failed to get `insert_span`'s line") + .line; + + 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())], + ); + }, + ); + } +} diff --git a/tests/ui/semicolon_outside_block_if_singleline.fixed b/tests/ui/semicolon_outside_block_if_singleline.fixed new file mode 100644 index 000000000000..592f9c49ed77 --- /dev/null +++ b/tests/ui/semicolon_outside_block_if_singleline.fixed @@ -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_if_singleline)] + +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() +} \ No newline at end of file diff --git a/tests/ui/semicolon_outside_block_if_singleline.rs b/tests/ui/semicolon_outside_block_if_singleline.rs new file mode 100644 index 000000000000..21dd61445a5b --- /dev/null +++ b/tests/ui/semicolon_outside_block_if_singleline.rs @@ -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_if_singleline)] + +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() +} \ No newline at end of file diff --git a/tests/ui/semicolon_outside_block_if_singleline.stderr b/tests/ui/semicolon_outside_block_if_singleline.stderr new file mode 100644 index 000000000000..dda083f2be3e --- /dev/null +++ b/tests/ui/semicolon_outside_block_if_singleline.stderr @@ -0,0 +1,54 @@ +error: consider moving the `;` outside the block for consistent formatting + --> $DIR/semicolon_outside_block_if_singleline.rs:42:5 + | +LL | { unit_fn_block(); } + | ^^^^^^^^^^^^^^^^^^^^ + | + = note: `-D clippy::semicolon-outside-block-if-singleline` 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_if_singleline.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 `;` inside the block for consistent formatting + --> $DIR/semicolon_outside_block_if_singleline.rs:48:5 + | +LL | / { +LL | | unit_fn_block(); +LL | | unit_fn_block() +LL | | }; + | |_____^ + | +help: put the `;` here + | +LL ~ unit_fn_block(); +LL ~ } + | + +error: consider moving the `;` outside the block for consistent formatting + --> $DIR/semicolon_outside_block_if_singleline.rs:62:5 + | +LL | { m!(()); } + | ^^^^^^^^^^^ + | +help: put the `;` here + | +LL - { m!(()); } +LL + { m!(()) }; + | + +error: aborting due to 4 previous errors + From dfccebe3e01e8c63ea0fc2833550123e45091e5b Mon Sep 17 00:00:00 2001 From: Centri3 <114838443+Centri3@users.noreply.github.com> Date: Sun, 16 Apr 2023 23:36:01 -0500 Subject: [PATCH 02/11] make cargo test pass --- clippy_lints/src/semicolon_block.rs | 4 ++-- tests/ui/semicolon_outside_block_if_singleline.fixed | 2 +- tests/ui/semicolon_outside_block_if_singleline.rs | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/clippy_lints/src/semicolon_block.rs b/clippy_lints/src/semicolon_block.rs index d791100b9b9a..eabe0e4619f6 100644 --- a/clippy_lints/src/semicolon_block.rs +++ b/clippy_lints/src/semicolon_block.rs @@ -83,7 +83,7 @@ declare_clippy_lint! { /// # fn f(_: u32) {} /// # let x = 0; /// unsafe { f(x); } - /// + /// /// unsafe { /// let x = 1; /// f(x) @@ -94,7 +94,7 @@ declare_clippy_lint! { /// # fn f(_: u32) {} /// # let x = 0; /// unsafe { f(x) }; - /// + /// /// unsafe { /// let x = 1; /// f(x); diff --git a/tests/ui/semicolon_outside_block_if_singleline.fixed b/tests/ui/semicolon_outside_block_if_singleline.fixed index 592f9c49ed77..e1ecbf8588d9 100644 --- a/tests/ui/semicolon_outside_block_if_singleline.fixed +++ b/tests/ui/semicolon_outside_block_if_singleline.fixed @@ -82,4 +82,4 @@ fn main() { { unit_fn_block(); }; unit_fn_block() -} \ No newline at end of file +} diff --git a/tests/ui/semicolon_outside_block_if_singleline.rs b/tests/ui/semicolon_outside_block_if_singleline.rs index 21dd61445a5b..80fbb4ce2d5e 100644 --- a/tests/ui/semicolon_outside_block_if_singleline.rs +++ b/tests/ui/semicolon_outside_block_if_singleline.rs @@ -82,4 +82,4 @@ fn main() { { unit_fn_block(); }; unit_fn_block() -} \ No newline at end of file +} From a7c3301b5884b33fc87f2e498f28426dfbcb1a84 Mon Sep 17 00:00:00 2001 From: Centri3 <114838443+Centri3@users.noreply.github.com> Date: Sun, 16 Apr 2023 23:56:21 -0500 Subject: [PATCH 03/11] refactor --- clippy_lints/src/semicolon_block.rs | 90 +++++++++++++++++++---------- 1 file changed, 61 insertions(+), 29 deletions(-) diff --git a/clippy_lints/src/semicolon_block.rs b/clippy_lints/src/semicolon_block.rs index eabe0e4619f6..d85d3b583058 100644 --- a/clippy_lints/src/semicolon_block.rs +++ b/clippy_lints/src/semicolon_block.rs @@ -125,11 +125,15 @@ impl LateLintPass<'_> for SemicolonBlock { .. } = stmt else { return }; semicolon_outside_block(cx, block, expr, span); + semicolon_outside_block_if_singleline_check_outside(cx, block, expr, stmt.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), + }) if !block.span.from_expansion() => { + semicolon_inside_block(cx, block, tail, stmt.span); + semicolon_outside_block_if_singleline_check_inside(cx, block, tail, stmt.span) + }, _ => (), } } @@ -139,8 +143,6 @@ fn semicolon_inside_block(cx: &LateContext<'_>, block: &Block<'_>, tail: &Expr<' let insert_span = tail.span.source_callsite().shrink_to_hi(); let remove_span = semi_span.with_lo(block.span.hi()); - check_semicolon_outside_block_if_singleline(cx, block, remove_span, insert_span, true, "inside"); - span_lint_and_then( cx, SEMICOLON_INSIDE_BLOCK, @@ -163,8 +165,6 @@ fn semicolon_outside_block(cx: &LateContext<'_>, block: &Block<'_>, tail_stmt_ex 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()); - check_semicolon_outside_block_if_singleline(cx, block, remove_span, insert_span, false, "outside"); - span_lint_and_then( cx, SEMICOLON_OUTSIDE_BLOCK, @@ -181,39 +181,54 @@ fn semicolon_outside_block(cx: &LateContext<'_>, block: &Block<'_>, tail_stmt_ex ); } -fn check_semicolon_outside_block_if_singleline( +fn semicolon_outside_block_if_singleline_check_inside( cx: &LateContext<'_>, block: &Block<'_>, - remove_span: Span, - insert_span: Span, - inequality: bool, - ty: &str, + tail: &Expr<'_>, + semi_span: Span, ) { - let remove_line = cx - .sess() - .source_map() - .lookup_line(remove_span.lo()) - .expect("failed to get `remove_span`'s line") - .line; - let insert_line = cx - .sess() - .source_map() - .lookup_line(insert_span.lo()) - .expect("failed to get `insert_span`'s line") - .line; + let insert_span = tail.span.source_callsite().shrink_to_hi(); + let remove_span = semi_span.with_lo(block.span.hi()); + + let (remove_line, insert_line) = get_line(cx, remove_span, insert_span); + + if insert_line != remove_line { + span_lint_and_then( + cx, + SEMICOLON_OUTSIDE_BLOCK_IF_SINGLELINE, + block.span, + &format!("consider moving the `;` inside the block for consistent formatting"), + |diag| { + multispan_sugg_with_applicability( + diag, + "put the `;` here", + Applicability::MachineApplicable, + [(remove_span, String::new()), (insert_span, ";".to_owned())], + ); + }, + ); + } +} - let eq = if inequality { - remove_line != insert_line - } else { - remove_line == insert_line - }; +fn semicolon_outside_block_if_singleline_check_outside( + 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()); + + let (remove_line, insert_line) = get_line(cx, remove_span, insert_span); - if eq { + if remove_line == insert_line { span_lint_and_then( cx, SEMICOLON_OUTSIDE_BLOCK_IF_SINGLELINE, block.span, - &format!("consider moving the `;` {ty} the block for consistent formatting"), + &format!("consider moving the `;` outside the block for consistent formatting"), |diag| { multispan_sugg_with_applicability( diag, @@ -225,3 +240,20 @@ fn check_semicolon_outside_block_if_singleline( ); } } + +fn get_line(cx: &LateContext<'_>, remove_span: Span, insert_span: Span) -> (usize, usize) { + let remove_line = cx + .sess() + .source_map() + .lookup_line(remove_span.lo()) + .expect("failed to get `remove_span`'s line") + .line; + let insert_line = cx + .sess() + .source_map() + .lookup_line(insert_span.lo()) + .expect("failed to get `insert_span`'s line") + .line; + + (remove_line, insert_line) +} From a57445d4d6c14adfd2103796a577805a04bb4db5 Mon Sep 17 00:00:00 2001 From: Centri3 <114838443+Centri3@users.noreply.github.com> Date: Sun, 16 Apr 2023 23:59:31 -0500 Subject: [PATCH 04/11] make cargo test pass, again --- clippy_lints/src/semicolon_block.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/clippy_lints/src/semicolon_block.rs b/clippy_lints/src/semicolon_block.rs index d85d3b583058..c9689454c63b 100644 --- a/clippy_lints/src/semicolon_block.rs +++ b/clippy_lints/src/semicolon_block.rs @@ -72,7 +72,7 @@ declare_clippy_lint! { /// /// ### Why is this bad? /// - /// Some may prefer if the semicolon is outside if a block is only one + /// Some may prefer if the semicolon is outside if a block is only one /// expression, as this allows rustfmt to make it singleline. 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. @@ -125,14 +125,14 @@ impl LateLintPass<'_> for SemicolonBlock { .. } = stmt else { return }; semicolon_outside_block(cx, block, expr, span); - semicolon_outside_block_if_singleline_check_outside(cx, block, expr, stmt.span) + semicolon_outside_block_if_singleline_check_outside(cx, block, expr, stmt.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_outside_block_if_singleline_check_inside(cx, block, tail, stmt.span) + semicolon_outside_block_if_singleline_check_inside(cx, block, tail, stmt.span); }, _ => (), } @@ -197,7 +197,7 @@ fn semicolon_outside_block_if_singleline_check_inside( cx, SEMICOLON_OUTSIDE_BLOCK_IF_SINGLELINE, block.span, - &format!("consider moving the `;` inside the block for consistent formatting"), + "consider moving the `;` inside the block for consistent formatting", |diag| { multispan_sugg_with_applicability( diag, @@ -228,7 +228,7 @@ fn semicolon_outside_block_if_singleline_check_outside( cx, SEMICOLON_OUTSIDE_BLOCK_IF_SINGLELINE, block.span, - &format!("consider moving the `;` outside the block for consistent formatting"), + "consider moving the `;` outside the block for consistent formatting", |diag| { multispan_sugg_with_applicability( diag, From 80707aa95faae4acf8b35abf0daf4626afdb446e Mon Sep 17 00:00:00 2001 From: Centri3 <114838443+Centri3@users.noreply.github.com> Date: Mon, 17 Apr 2023 00:37:43 -0500 Subject: [PATCH 05/11] improve description a bit --- clippy_lints/src/semicolon_block.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/clippy_lints/src/semicolon_block.rs b/clippy_lints/src/semicolon_block.rs index c9689454c63b..8cdfbd5c495a 100644 --- a/clippy_lints/src/semicolon_block.rs +++ b/clippy_lints/src/semicolon_block.rs @@ -72,10 +72,11 @@ declare_clippy_lint! { /// /// ### Why is this bad? /// - /// Some may prefer if the semicolon is outside if a block is only one - /// expression, as this allows rustfmt to make it singleline. 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. + /// 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 /// From fa1efa8b104c71721d8317ae59819f6abf2d0ac8 Mon Sep 17 00:00:00 2001 From: Centri3 <114838443+Centri3@users.noreply.github.com> Date: Mon, 17 Apr 2023 20:57:56 -0500 Subject: [PATCH 06/11] refactor --- clippy_lints/src/semicolon_block.rs | 77 +++++++++-------------------- 1 file changed, 22 insertions(+), 55 deletions(-) diff --git a/clippy_lints/src/semicolon_block.rs b/clippy_lints/src/semicolon_block.rs index 8cdfbd5c495a..7113f0c55d4d 100644 --- a/clippy_lints/src/semicolon_block.rs +++ b/clippy_lints/src/semicolon_block.rs @@ -126,14 +126,12 @@ impl LateLintPass<'_> for SemicolonBlock { .. } = stmt else { return }; semicolon_outside_block(cx, block, expr, span); - semicolon_outside_block_if_singleline_check_outside(cx, block, expr, stmt.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_outside_block_if_singleline_check_inside(cx, block, tail, stmt.span); }, _ => (), } @@ -144,6 +142,8 @@ fn semicolon_inside_block(cx: &LateContext<'_>, block: &Block<'_>, tail: &Expr<' 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"); + span_lint_and_then( cx, SEMICOLON_INSIDE_BLOCK, @@ -166,6 +166,8 @@ fn semicolon_outside_block(cx: &LateContext<'_>, block: &Block<'_>, tail_stmt_ex 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"); + span_lint_and_then( cx, SEMICOLON_OUTSIDE_BLOCK, @@ -182,23 +184,28 @@ fn semicolon_outside_block(cx: &LateContext<'_>, block: &Block<'_>, tail_stmt_ex ); } -fn semicolon_outside_block_if_singleline_check_inside( +fn semicolon_outside_block_if_singleline( cx: &LateContext<'_>, block: &Block<'_>, - tail: &Expr<'_>, - semi_span: Span, + remove_span: Span, + insert_span: Span, + inequality: bool, + ty: &str, ) { - let insert_span = tail.span.source_callsite().shrink_to_hi(); - let remove_span = semi_span.with_lo(block.span.hi()); + let (remove_line, insert_line) = (get_line(cx, remove_span), get_line(cx, insert_span)); - let (remove_line, insert_line) = get_line(cx, remove_span, insert_span); + let eq = if inequality { + remove_line != insert_line + } else { + remove_line == insert_line + }; - if insert_line != remove_line { + if eq { span_lint_and_then( cx, SEMICOLON_OUTSIDE_BLOCK_IF_SINGLELINE, block.span, - "consider moving the `;` inside the block for consistent formatting", + &format!("consider moving the `;` {ty} the block for consistent formatting"), |diag| { multispan_sugg_with_applicability( diag, @@ -211,50 +218,10 @@ fn semicolon_outside_block_if_singleline_check_inside( } } -fn semicolon_outside_block_if_singleline_check_outside( - 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()); - - let (remove_line, insert_line) = get_line(cx, remove_span, insert_span); - - if remove_line == insert_line { - span_lint_and_then( - cx, - SEMICOLON_OUTSIDE_BLOCK_IF_SINGLELINE, - block.span, - "consider moving the `;` outside 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<'_>, remove_span: Span, insert_span: Span) -> (usize, usize) { - let remove_line = cx - .sess() - .source_map() - .lookup_line(remove_span.lo()) - .expect("failed to get `remove_span`'s line") - .line; - let insert_line = cx - .sess() +fn get_line(cx: &LateContext<'_>, span: Span) -> usize { + cx.sess() .source_map() - .lookup_line(insert_span.lo()) - .expect("failed to get `insert_span`'s line") - .line; - - (remove_line, insert_line) + .lookup_line(span.lo()) + .expect("failed to get span's line") + .line } From a3aeec4f75dd0049f6632e26df5aa174b55e730f Mon Sep 17 00:00:00 2001 From: Centri3 <114838443+Centri3@users.noreply.github.com> Date: Wed, 19 Apr 2023 21:46:13 -0500 Subject: [PATCH 07/11] config instead of new lint and don't panic --- CHANGELOG.md | 1 - clippy_lints/src/declared_lints.rs | 1 - clippy_lints/src/lib.rs | 9 +- clippy_lints/src/semicolon_block.rs | 127 ++++++------------ clippy_lints/src/utils/conf.rs | 8 ++ .../semicolon_block/both.fixed} | 3 +- tests/ui-toml/semicolon_block/both.rs | 86 ++++++++++++ .../semicolon_block/both.stderr} | 13 +- tests/ui-toml/semicolon_block/clippy.toml | 2 + .../semicolon_inside_block.fixed | 85 ++++++++++++ .../semicolon_inside_block.rs} | 2 +- .../semicolon_inside_block.stderr | 18 +++ .../semicolon_outside_block.fixed | 85 ++++++++++++ .../semicolon_outside_block.rs | 85 ++++++++++++ .../semicolon_outside_block.stderr | 39 ++++++ .../toml_unknown_key/conf_unknown_key.stderr | 2 + 16 files changed, 468 insertions(+), 98 deletions(-) rename tests/{ui/semicolon_outside_block_if_singleline.fixed => ui-toml/semicolon_block/both.fixed} (93%) create mode 100644 tests/ui-toml/semicolon_block/both.rs rename tests/{ui/semicolon_outside_block_if_singleline.stderr => ui-toml/semicolon_block/both.stderr} (75%) create mode 100644 tests/ui-toml/semicolon_block/clippy.toml create mode 100644 tests/ui-toml/semicolon_block/semicolon_inside_block.fixed rename tests/{ui/semicolon_outside_block_if_singleline.rs => ui-toml/semicolon_block/semicolon_inside_block.rs} (95%) create mode 100644 tests/ui-toml/semicolon_block/semicolon_inside_block.stderr create mode 100644 tests/ui-toml/semicolon_block/semicolon_outside_block.fixed create mode 100644 tests/ui-toml/semicolon_block/semicolon_outside_block.rs create mode 100644 tests/ui-toml/semicolon_block/semicolon_outside_block.stderr diff --git a/CHANGELOG.md b/CHANGELOG.md index a0a7780f4c27..559b560dde4b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/clippy_lints/src/declared_lints.rs b/clippy_lints/src/declared_lints.rs index 70379b6caf11..f24dab627809 100644 --- a/clippy_lints/src/declared_lints.rs +++ b/clippy_lints/src/declared_lints.rs @@ -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, diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index b0ec14855e71..cb223ce9d16a 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -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)); diff --git a/clippy_lints/src/semicolon_block.rs b/clippy_lints/src/semicolon_block.rs index 7113f0c55d4d..6be430337122 100644 --- a/clippy_lints/src/semicolon_block.rs +++ b/clippy_lints/src/semicolon_block.rs @@ -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 { + 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 } diff --git a/clippy_lints/src/utils/conf.rs b/clippy_lints/src/utils/conf.rs index 896a01af37d9..26123549b94c 100644 --- a/clippy_lints/src/utils/conf.rs +++ b/clippy_lints/src/utils/conf.rs @@ -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. diff --git a/tests/ui/semicolon_outside_block_if_singleline.fixed b/tests/ui-toml/semicolon_block/both.fixed similarity index 93% rename from tests/ui/semicolon_outside_block_if_singleline.fixed rename to tests/ui-toml/semicolon_block/both.fixed index e1ecbf8588d9..981b661bc786 100644 --- a/tests/ui/semicolon_outside_block_if_singleline.fixed +++ b/tests/ui-toml/semicolon_block/both.fixed @@ -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 { (()) => { diff --git a/tests/ui-toml/semicolon_block/both.rs b/tests/ui-toml/semicolon_block/both.rs new file mode 100644 index 000000000000..d4dcd6e7240e --- /dev/null +++ b/tests/ui-toml/semicolon_block/both.rs @@ -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() +} diff --git a/tests/ui/semicolon_outside_block_if_singleline.stderr b/tests/ui-toml/semicolon_block/both.stderr similarity index 75% rename from tests/ui/semicolon_outside_block_if_singleline.stderr rename to tests/ui-toml/semicolon_block/both.stderr index dda083f2be3e..2f58842eab01 100644 --- a/tests/ui/semicolon_outside_block_if_singleline.stderr +++ b/tests/ui-toml/semicolon_block/both.stderr @@ -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!(()); } | ^^^^^^^^^^^ diff --git a/tests/ui-toml/semicolon_block/clippy.toml b/tests/ui-toml/semicolon_block/clippy.toml new file mode 100644 index 000000000000..cc3bc8cae14b --- /dev/null +++ b/tests/ui-toml/semicolon_block/clippy.toml @@ -0,0 +1,2 @@ +semicolon-inside-block-if-multiline = true +semicolon-outside-block-if-singleline = true diff --git a/tests/ui-toml/semicolon_block/semicolon_inside_block.fixed b/tests/ui-toml/semicolon_block/semicolon_inside_block.fixed new file mode 100644 index 000000000000..6a08bc905b11 --- /dev/null +++ b/tests/ui-toml/semicolon_block/semicolon_inside_block.fixed @@ -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() +} diff --git a/tests/ui/semicolon_outside_block_if_singleline.rs b/tests/ui-toml/semicolon_block/semicolon_inside_block.rs similarity index 95% rename from tests/ui/semicolon_outside_block_if_singleline.rs rename to tests/ui-toml/semicolon_block/semicolon_inside_block.rs index 80fbb4ce2d5e..f40848f702e1 100644 --- a/tests/ui/semicolon_outside_block_if_singleline.rs +++ b/tests/ui-toml/semicolon_block/semicolon_inside_block.rs @@ -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 { (()) => { diff --git a/tests/ui-toml/semicolon_block/semicolon_inside_block.stderr b/tests/ui-toml/semicolon_block/semicolon_inside_block.stderr new file mode 100644 index 000000000000..2569dc4b4e45 --- /dev/null +++ b/tests/ui-toml/semicolon_block/semicolon_inside_block.stderr @@ -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 + diff --git a/tests/ui-toml/semicolon_block/semicolon_outside_block.fixed b/tests/ui-toml/semicolon_block/semicolon_outside_block.fixed new file mode 100644 index 000000000000..e2d653dc3c35 --- /dev/null +++ b/tests/ui-toml/semicolon_block/semicolon_outside_block.fixed @@ -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() +} diff --git a/tests/ui-toml/semicolon_block/semicolon_outside_block.rs b/tests/ui-toml/semicolon_block/semicolon_outside_block.rs new file mode 100644 index 000000000000..7ce46431fac9 --- /dev/null +++ b/tests/ui-toml/semicolon_block/semicolon_outside_block.rs @@ -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() +} diff --git a/tests/ui-toml/semicolon_block/semicolon_outside_block.stderr b/tests/ui-toml/semicolon_block/semicolon_outside_block.stderr new file mode 100644 index 000000000000..6dd3577dd09f --- /dev/null +++ b/tests/ui-toml/semicolon_block/semicolon_outside_block.stderr @@ -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 + diff --git a/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr b/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr index 8447c31722dd..c49c9087946d 100644 --- a/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr +++ b/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr @@ -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 From 41f6d88be588b191d7c49547819671c11c9a84e9 Mon Sep 17 00:00:00 2001 From: Centri3 <114838443+Centri3@users.noreply.github.com> Date: Wed, 19 Apr 2023 21:51:58 -0500 Subject: [PATCH 08/11] make cargo test pass --- clippy_lints/src/semicolon_block.rs | 20 +++++++++++--------- clippy_lints/src/utils/conf.rs | 16 ++++++++-------- 2 files changed, 19 insertions(+), 17 deletions(-) diff --git a/clippy_lints/src/semicolon_block.rs b/clippy_lints/src/semicolon_block.rs index 6be430337122..c1c0325b786b 100644 --- a/clippy_lints/src/semicolon_block.rs +++ b/clippy_lints/src/semicolon_block.rs @@ -121,10 +121,8 @@ fn semicolon_inside_block( let insert_span = tail.span.source_callsite().shrink_to_hi(); let remove_span = semi_span.with_lo(block.span.hi()); - if conf.semicolon_inside_block_if_multiline { - if get_line(cx, remove_span) == get_line(cx, insert_span) { - return; - } + if conf.semicolon_inside_block_if_multiline && get_line(cx, remove_span) == get_line(cx, insert_span) { + return; } span_lint_and_then( @@ -143,16 +141,20 @@ fn semicolon_inside_block( ); } -fn semicolon_outside_block(conf: &mut SemicolonBlock, 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()); - if conf.semicolon_outside_block_if_singleline { - if get_line(cx, remove_span) != get_line(cx, insert_span) { - return; - } + if conf.semicolon_outside_block_if_singleline && get_line(cx, remove_span) != get_line(cx, insert_span) { + return; } span_lint_and_then( diff --git a/clippy_lints/src/utils/conf.rs b/clippy_lints/src/utils/conf.rs index 26123549b94c..939f6cd5f1fc 100644 --- a/clippy_lints/src/utils/conf.rs +++ b/clippy_lints/src/utils/conf.rs @@ -277,6 +277,14 @@ define_Conf! { /// `".."` can be used as part of the list to indicate, that the configured values should be appended to the /// default configuration of Clippy. By default, any configuration will replace the default value. (disallowed_names: Vec = super::DEFAULT_DISALLOWED_NAMES.iter().map(ToString::to_string).collect()), + /// 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), /// Lint: DOC_MARKDOWN. /// /// The list of words this lint should not consider as identifiers needing ticks. The value @@ -463,14 +471,6 @@ 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. From aa6c27a74e00e8e98cd3ce3e0db6149bb5bc7bcf Mon Sep 17 00:00:00 2001 From: Centri3 <114838443+Centri3@users.noreply.github.com> Date: Tue, 25 Apr 2023 11:14:52 -0500 Subject: [PATCH 09/11] change names to not be implicitly negative --- clippy_lints/src/lib.rs | 8 +- clippy_lints/src/semicolon_block.rs | 132 +++++++++--------- clippy_lints/src/utils/conf.rs | 4 +- tests/ui-toml/semicolon_block/clippy.toml | 4 +- .../toml_unknown_key/conf_unknown_key.stderr | 4 +- 5 files changed, 73 insertions(+), 79 deletions(-) diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index cb223ce9d16a..d8bfb84537d7 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -932,12 +932,12 @@ 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()))); - let semicolon_inside_block_if_multiline = conf.semicolon_inside_block_if_multiline; - let semicolon_outside_block_if_singleline = conf.semicolon_outside_block_if_singleline; + let semicolon_inside_block_ignore_singleline = conf.semicolon_inside_block_ignore_singleline; + let semicolon_outside_block_ignore_multiline = conf.semicolon_outside_block_ignore_multiline; store.register_late_pass(move |_| { Box::new(semicolon_block::SemicolonBlock::new( - semicolon_inside_block_if_multiline, - semicolon_outside_block_if_singleline, + semicolon_inside_block_ignore_singleline, + semicolon_outside_block_ignore_multiline, )) }); store.register_late_pass(|_| Box::new(fn_null_check::FnNullCheck)); diff --git a/clippy_lints/src/semicolon_block.rs b/clippy_lints/src/semicolon_block.rs index c1c0325b786b..419d7991f0ec 100644 --- a/clippy_lints/src/semicolon_block.rs +++ b/clippy_lints/src/semicolon_block.rs @@ -68,17 +68,73 @@ impl_lint_pass!(SemicolonBlock => [SEMICOLON_INSIDE_BLOCK, SEMICOLON_OUTSIDE_BLO #[derive(Copy, Clone)] pub struct SemicolonBlock { - semicolon_inside_block_if_multiline: bool, - semicolon_outside_block_if_singleline: bool, + semicolon_inside_block_ignore_singleline: bool, + semicolon_outside_block_ignore_multiline: bool, } impl SemicolonBlock { - pub fn new(semicolon_inside_block_if_multiline: bool, semicolon_outside_block_if_singleline: bool) -> Self { + pub fn new(semicolon_inside_block_ignore_singleline: bool, semicolon_outside_block_ignore_multiline: bool) -> Self { Self { - semicolon_inside_block_if_multiline, - semicolon_outside_block_if_singleline, + semicolon_inside_block_ignore_singleline, + semicolon_outside_block_ignore_multiline, } } + + fn semicolon_inside_block(self, 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()); + + if self.semicolon_inside_block_ignore_singleline && get_line(cx, remove_span) == get_line(cx, insert_span) { + return; + } + + span_lint_and_then( + cx, + SEMICOLON_INSIDE_BLOCK, + semi_span, + "consider moving the `;` inside 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 semicolon_outside_block( + self, + 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()); + + if self.semicolon_outside_block_ignore_multiline && get_line(cx, remove_span) != get_line(cx, insert_span) { + return; + } + + span_lint_and_then( + cx, + SEMICOLON_OUTSIDE_BLOCK, + block.span, + "consider moving the `;` outside the block for consistent formatting", + |diag| { + multispan_sugg_with_applicability( + diag, + "put the `;` here", + Applicability::MachineApplicable, + [(remove_span, String::new()), (insert_span, ";".to_owned())], + ); + }, + ); + } } impl LateLintPass<'_> for SemicolonBlock { @@ -98,81 +154,19 @@ impl LateLintPass<'_> for SemicolonBlock { span, .. } = stmt else { return }; - semicolon_outside_block(self, cx, block, expr, span); + self.semicolon_outside_block(cx, block, expr, span); }, StmtKind::Semi(Expr { kind: ExprKind::Block(block @ Block { expr: Some(tail), .. }, _), .. }) if !block.span.from_expansion() => { - semicolon_inside_block(self, cx, block, tail, stmt.span); + self.semicolon_inside_block(cx, block, tail, stmt.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()); - - if conf.semicolon_inside_block_if_multiline && get_line(cx, remove_span) == get_line(cx, insert_span) { - return; - } - - span_lint_and_then( - cx, - SEMICOLON_INSIDE_BLOCK, - semi_span, - "consider moving the `;` inside 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 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()); - - if conf.semicolon_outside_block_if_singleline && get_line(cx, remove_span) != get_line(cx, insert_span) { - return; - } - - span_lint_and_then( - cx, - SEMICOLON_OUTSIDE_BLOCK, - block.span, - "consider moving the `;` outside 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 { if let Ok(line) = cx.sess().source_map().lookup_line(span.lo()) { return Some(line.line); diff --git a/clippy_lints/src/utils/conf.rs b/clippy_lints/src/utils/conf.rs index 939f6cd5f1fc..18a6e2a4a3a6 100644 --- a/clippy_lints/src/utils/conf.rs +++ b/clippy_lints/src/utils/conf.rs @@ -280,11 +280,11 @@ define_Conf! { /// Lint: SEMICOLON_INSIDE_BLOCK. /// /// Whether to lint only if it's multiline. - (semicolon_inside_block_if_multiline: bool = false), + (semicolon_inside_block_ignore_singleline: bool = false), /// Lint: SEMICOLON_OUTSIDE_BLOCK. /// /// Whether to lint only if it's singleline. - (semicolon_outside_block_if_singleline: bool = false), + (semicolon_outside_block_ignore_multiline: bool = false), /// Lint: DOC_MARKDOWN. /// /// The list of words this lint should not consider as identifiers needing ticks. The value diff --git a/tests/ui-toml/semicolon_block/clippy.toml b/tests/ui-toml/semicolon_block/clippy.toml index cc3bc8cae14b..4d03e88deba8 100644 --- a/tests/ui-toml/semicolon_block/clippy.toml +++ b/tests/ui-toml/semicolon_block/clippy.toml @@ -1,2 +1,2 @@ -semicolon-inside-block-if-multiline = true -semicolon-outside-block-if-singleline = true +semicolon-inside-block-ignore-singleline = true +semicolon-outside-block-ignore-multiline = true diff --git a/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr b/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr index c49c9087946d..1e0d7499c7e7 100644 --- a/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr +++ b/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr @@ -37,8 +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 + semicolon-inside-block-ignore-singleline + semicolon-outside-block-ignore-multiline single-char-binding-names-threshold standard-macro-braces suppress-restriction-lint-in-const From e3ee10d42851fa2fd88216773b6835b5125e1ddc Mon Sep 17 00:00:00 2001 From: Centri3 <114838443+Centri3@users.noreply.github.com> Date: Tue, 25 Apr 2023 11:23:02 -0500 Subject: [PATCH 10/11] use `//@` for commands in tests --- tests/ui-toml/semicolon_block/both.fixed | 2 +- tests/ui-toml/semicolon_block/both.rs | 2 +- tests/ui-toml/semicolon_block/semicolon_inside_block.fixed | 2 +- tests/ui-toml/semicolon_block/semicolon_inside_block.rs | 2 +- tests/ui-toml/semicolon_block/semicolon_outside_block.fixed | 2 +- tests/ui-toml/semicolon_block/semicolon_outside_block.rs | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/ui-toml/semicolon_block/both.fixed b/tests/ui-toml/semicolon_block/both.fixed index 981b661bc786..fc8038a09071 100644 --- a/tests/ui-toml/semicolon_block/both.fixed +++ b/tests/ui-toml/semicolon_block/both.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow( unused, clippy::unused_unit, diff --git a/tests/ui-toml/semicolon_block/both.rs b/tests/ui-toml/semicolon_block/both.rs index d4dcd6e7240e..52ce1f0387ee 100644 --- a/tests/ui-toml/semicolon_block/both.rs +++ b/tests/ui-toml/semicolon_block/both.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow( unused, clippy::unused_unit, diff --git a/tests/ui-toml/semicolon_block/semicolon_inside_block.fixed b/tests/ui-toml/semicolon_block/semicolon_inside_block.fixed index 6a08bc905b11..23df98301773 100644 --- a/tests/ui-toml/semicolon_block/semicolon_inside_block.fixed +++ b/tests/ui-toml/semicolon_block/semicolon_inside_block.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow( unused, clippy::unused_unit, diff --git a/tests/ui-toml/semicolon_block/semicolon_inside_block.rs b/tests/ui-toml/semicolon_block/semicolon_inside_block.rs index f40848f702e1..e8516f79b20c 100644 --- a/tests/ui-toml/semicolon_block/semicolon_inside_block.rs +++ b/tests/ui-toml/semicolon_block/semicolon_inside_block.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow( unused, clippy::unused_unit, diff --git a/tests/ui-toml/semicolon_block/semicolon_outside_block.fixed b/tests/ui-toml/semicolon_block/semicolon_outside_block.fixed index e2d653dc3c35..7e9055e71106 100644 --- a/tests/ui-toml/semicolon_block/semicolon_outside_block.fixed +++ b/tests/ui-toml/semicolon_block/semicolon_outside_block.fixed @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow( unused, clippy::unused_unit, diff --git a/tests/ui-toml/semicolon_block/semicolon_outside_block.rs b/tests/ui-toml/semicolon_block/semicolon_outside_block.rs index 7ce46431fac9..4dc956d8a4b5 100644 --- a/tests/ui-toml/semicolon_block/semicolon_outside_block.rs +++ b/tests/ui-toml/semicolon_block/semicolon_outside_block.rs @@ -1,4 +1,4 @@ -// run-rustfix +//@run-rustfix #![allow( unused, clippy::unused_unit, From 8c8cf407074b2a1d56a285a575035e1c454c3195 Mon Sep 17 00:00:00 2001 From: Centri3 <114838443+Centri3@users.noreply.github.com> Date: Tue, 25 Apr 2023 14:44:56 -0500 Subject: [PATCH 11/11] Update lint_configuration.md --- book/src/lint_configuration.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/book/src/lint_configuration.md b/book/src/lint_configuration.md index 78e1a55cff32..16d19965868c 100644 --- a/book/src/lint_configuration.md +++ b/book/src/lint_configuration.md @@ -13,6 +13,8 @@ Please use that command to update the file and do not edit it by hand. | [msrv](#msrv) | `None` | | [cognitive-complexity-threshold](#cognitive-complexity-threshold) | `25` | | [disallowed-names](#disallowed-names) | `["foo", "baz", "quux"]` | +| [semicolon-inside-block-ignore-singleline](#semicolon-inside-block-ignore-singleline) | `false` | +| [semicolon-outside-block-ignore-multiline](#semicolon-outside-block-ignore-multiline) | `false` | | [doc-valid-idents](#doc-valid-idents) | `["KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "DirectX", "ECMAScript", "GPLv2", "GPLv3", "GitHub", "GitLab", "IPv4", "IPv6", "ClojureScript", "CoffeeScript", "JavaScript", "PureScript", "TypeScript", "NaN", "NaNs", "OAuth", "GraphQL", "OCaml", "OpenGL", "OpenMP", "OpenSSH", "OpenSSL", "OpenStreetMap", "OpenDNS", "WebGL", "TensorFlow", "TrueType", "iOS", "macOS", "FreeBSD", "TeX", "LaTeX", "BibTeX", "BibLaTeX", "MinGW", "CamelCase"]` | | [too-many-arguments-threshold](#too-many-arguments-threshold) | `7` | | [type-complexity-threshold](#type-complexity-threshold) | `250` | @@ -202,6 +204,22 @@ default configuration of Clippy. By default, any configuration will replace the * [disallowed_names](https://rust-lang.github.io/rust-clippy/master/index.html#disallowed_names) +### semicolon-inside-block-ignore-singleline +Whether to lint only if it's multiline. + +**Default Value:** `false` (`bool`) + +* [semicolon_inside_block](https://rust-lang.github.io/rust-clippy/master/index.html#semicolon_inside_block) + + +### semicolon-outside-block-ignore-multiline +Whether to lint only if it's singleline. + +**Default Value:** `false` (`bool`) + +* [semicolon_outside_block](https://rust-lang.github.io/rust-clippy/master/index.html#semicolon_outside_block) + + ### doc-valid-idents The list of words this lint should not consider as identifiers needing ticks. The value `".."` can be used as part of the list to indicate, that the configured values should be appended to the