about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAda Alakbarova <ada.alakbarova@proton.me>2025-08-02 10:50:04 +0200
committerAda Alakbarova <ada.alakbarova@proton.me>2025-09-08 21:24:04 +0200
commit36c2c0a8bab6fb5c588ee6980fd8c1be659567c2 (patch)
tree56da0b3647103c4ee317c50684692c80f63464b2
parent368b2355797b13511776f0a35ec4864468b87ece (diff)
downloadrust-36c2c0a8bab6fb5c588ee6980fd8c1be659567c2.tar.gz
rust-36c2c0a8bab6fb5c588ee6980fd8c1be659567c2.zip
fix(semicolon_inside_block): don't lint if block is in parens
-rw-r--r--clippy_lints/src/semicolon_block.rs14
-rw-r--r--tests/ui/semicolon_inside_block.fixed17
-rw-r--r--tests/ui/semicolon_inside_block.rs17
-rw-r--r--tests/ui/semicolon_inside_block.stderr8
4 files changed, 50 insertions, 6 deletions
diff --git a/clippy_lints/src/semicolon_block.rs b/clippy_lints/src/semicolon_block.rs
index 1dea8f17c34..371d62a0684 100644
--- a/clippy_lints/src/semicolon_block.rs
+++ b/clippy_lints/src/semicolon_block.rs
@@ -1,5 +1,6 @@
 use clippy_config::Conf;
 use clippy_utils::diagnostics::span_lint_and_then;
+use clippy_utils::source::SpanRangeExt;
 use rustc_errors::Applicability;
 use rustc_hir::{Block, Expr, ExprKind, Stmt, StmtKind};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
@@ -82,6 +83,19 @@ impl SemicolonBlock {
         let insert_span = tail.span.source_callsite().shrink_to_hi();
         let remove_span = semi_span.with_lo(block.span.hi());
 
+        // If the block is surrounded by parens (`({ 0 });`), the author probably knows what
+        // they're doing and why, so don't get in their way.
+        //
+        // This has the additional benefit of stopping the block being parsed as a function call:
+        // ```
+        // fn foo() {
+        //     ({ 0 }); // if we remove this `;`, this will parse as a `({ 0 })(5);` function call
+        //     (5);
+        // }
+        if remove_span.check_source_text(cx, |src| src.contains(')')) {
+            return;
+        }
+
         if self.semicolon_inside_block_ignore_singleline && get_line(cx, remove_span) == get_line(cx, insert_span) {
             return;
         }
diff --git a/tests/ui/semicolon_inside_block.fixed b/tests/ui/semicolon_inside_block.fixed
index 7308e78aae2..468f0a5b1e4 100644
--- a/tests/ui/semicolon_inside_block.fixed
+++ b/tests/ui/semicolon_inside_block.fixed
@@ -3,7 +3,8 @@
     clippy::unused_unit,
     clippy::unnecessary_operation,
     clippy::no_effect,
-    clippy::single_element_loop
+    clippy::single_element_loop,
+    clippy::double_parens
 )]
 #![warn(clippy::semicolon_inside_block)]
 
@@ -87,6 +88,20 @@ fn main() {
     unit_fn_block()
 }
 
+#[rustfmt::skip]
+fn issue15380() {
+    ( {0;0});
+
+    ({
+        0;
+        0
+    });
+
+    (({ 0 }))      ;
+
+    ( ( { 0 } ) ) ;
+}
+
 pub fn issue15388() {
     #[rustfmt::skip]
     {0; 0};
diff --git a/tests/ui/semicolon_inside_block.rs b/tests/ui/semicolon_inside_block.rs
index 467bf4d779f..101374af264 100644
--- a/tests/ui/semicolon_inside_block.rs
+++ b/tests/ui/semicolon_inside_block.rs
@@ -3,7 +3,8 @@
     clippy::unused_unit,
     clippy::unnecessary_operation,
     clippy::no_effect,
-    clippy::single_element_loop
+    clippy::single_element_loop,
+    clippy::double_parens
 )]
 #![warn(clippy::semicolon_inside_block)]
 
@@ -87,6 +88,20 @@ fn main() {
     unit_fn_block()
 }
 
+#[rustfmt::skip]
+fn issue15380() {
+    ( {0;0});
+
+    ({
+        0;
+        0
+    });
+
+    (({ 0 }))      ;
+
+    ( ( { 0 } ) ) ;
+}
+
 pub fn issue15388() {
     #[rustfmt::skip]
     {0; 0};
diff --git a/tests/ui/semicolon_inside_block.stderr b/tests/ui/semicolon_inside_block.stderr
index 23433f4e7ef..2046dd1c36b 100644
--- a/tests/ui/semicolon_inside_block.stderr
+++ b/tests/ui/semicolon_inside_block.stderr
@@ -1,5 +1,5 @@
 error: consider moving the `;` inside the block for consistent formatting
-  --> tests/ui/semicolon_inside_block.rs:38:5
+  --> tests/ui/semicolon_inside_block.rs:39:5
    |
 LL |     { unit_fn_block() };
    |     ^^^^^^^^^^^^^^^^^^^^
@@ -13,7 +13,7 @@ LL +     { unit_fn_block(); }
    |
 
 error: consider moving the `;` inside the block for consistent formatting
-  --> tests/ui/semicolon_inside_block.rs:40:5
+  --> tests/ui/semicolon_inside_block.rs:41:5
    |
 LL |     unsafe { unit_fn_block() };
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -25,7 +25,7 @@ LL +     unsafe { unit_fn_block(); }
    |
 
 error: consider moving the `;` inside the block for consistent formatting
-  --> tests/ui/semicolon_inside_block.rs:49:5
+  --> tests/ui/semicolon_inside_block.rs:50:5
    |
 LL | /     {
 LL | |
@@ -41,7 +41,7 @@ LL ~     }
    |
 
 error: consider moving the `;` inside the block for consistent formatting
-  --> tests/ui/semicolon_inside_block.rs:63:5
+  --> tests/ui/semicolon_inside_block.rs:64:5
    |
 LL |     { m!(()) };
    |     ^^^^^^^^^^^