about summary refs log tree commit diff
diff options
context:
space:
mode:
authory21 <30553356+y21@users.noreply.github.com>2024-10-20 19:00:55 +0200
committery21 <30553356+y21@users.noreply.github.com>2024-10-20 19:00:55 +0200
commit65eb1ec0fbc72df2fa6122fa061cd73fc7140612 (patch)
tree027f016dad5a87cf4731bebdb738a5cc3ab580ad
parent4de65a113f3f15cfc674c7b77cfa3afe1ddbe090 (diff)
downloadrust-65eb1ec0fbc72df2fa6122fa061cd73fc7140612.tar.gz
rust-65eb1ec0fbc72df2fa6122fa061cd73fc7140612.zip
remove the semicolon for builtin macro call statements in `statement_outside_block`
The expansion of `asm!()` and `line!()` is not marked as from an expansion, in which case `SourceMap::stmt_span` returns the input span unchanged. So instead of using `stmt_span`, use `mac_call_stmt_semi_span` directly
-rw-r--r--clippy_lints/src/semicolon_block.rs27
-rw-r--r--tests/ui/semicolon_outside_block.fixed8
-rw-r--r--tests/ui/semicolon_outside_block.rs8
-rw-r--r--tests/ui/semicolon_outside_block.stderr30
4 files changed, 60 insertions, 13 deletions
diff --git a/clippy_lints/src/semicolon_block.rs b/clippy_lints/src/semicolon_block.rs
index 09f1c112352..d85f4a8fa01 100644
--- a/clippy_lints/src/semicolon_block.rs
+++ b/clippy_lints/src/semicolon_block.rs
@@ -101,17 +101,21 @@ impl SemicolonBlock {
         );
     }
 
-    fn semicolon_outside_block(
-        &self,
-        cx: &LateContext<'_>,
-        block: &Block<'_>,
-        tail_stmt_expr: &Expr<'_>,
-        semi_span: Span,
-    ) {
+    fn semicolon_outside_block(&self, cx: &LateContext<'_>, block: &Block<'_>, tail_stmt_expr: &Expr<'_>) {
         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());
+
+        // For macro call semicolon statements (`mac!();`), the statement's span does not actually
+        // include the semicolon itself, so use `mac_call_stmt_semi_span`, which finds the semicolon
+        // based on a source snippet.
+        // (Does not use `stmt_span` as that requires `.from_expansion()` to return true,
+        // which is not the case for e.g. `line!();` and `asm!();`)
+        let Some(remove_span) = cx
+            .sess()
+            .source_map()
+            .mac_call_stmt_semi_span(tail_stmt_expr.span.source_callsite())
+        else {
+            return;
+        };
 
         if self.semicolon_outside_block_ignore_multiline && get_line(cx, remove_span) != get_line(cx, insert_span) {
             return;
@@ -150,13 +154,12 @@ impl LateLintPass<'_> for SemicolonBlock {
                 };
                 let &Stmt {
                     kind: StmtKind::Semi(expr),
-                    span,
                     ..
                 } = stmt
                 else {
                     return;
                 };
-                self.semicolon_outside_block(cx, block, expr, span);
+                self.semicolon_outside_block(cx, block, expr);
             },
             StmtKind::Semi(Expr {
                 kind: ExprKind::Block(block @ Block { expr: Some(tail), .. }, _),
diff --git a/tests/ui/semicolon_outside_block.fixed b/tests/ui/semicolon_outside_block.fixed
index 148e112e0bc..ac7e86631ca 100644
--- a/tests/ui/semicolon_outside_block.fixed
+++ b/tests/ui/semicolon_outside_block.fixed
@@ -80,5 +80,13 @@ fn main() {
 
     { unit_fn_block(); };
 
+    unsafe {
+        std::arch::asm!("")
+    };
+
+    {
+        line!()
+    };
+
     unit_fn_block()
 }
diff --git a/tests/ui/semicolon_outside_block.rs b/tests/ui/semicolon_outside_block.rs
index c767201469a..68f25339e32 100644
--- a/tests/ui/semicolon_outside_block.rs
+++ b/tests/ui/semicolon_outside_block.rs
@@ -80,5 +80,13 @@ fn main() {
 
     { unit_fn_block(); };
 
+    unsafe {
+        std::arch::asm!("");
+    }
+
+    {
+        line!();
+    }
+
     unit_fn_block()
 }
diff --git a/tests/ui/semicolon_outside_block.stderr b/tests/ui/semicolon_outside_block.stderr
index 68b44c8f980..ff8c00048f6 100644
--- a/tests/ui/semicolon_outside_block.stderr
+++ b/tests/ui/semicolon_outside_block.stderr
@@ -51,5 +51,33 @@ LL -     { m!(()); }
 LL +     { m!(()) };
    |
 
-error: aborting due to 4 previous errors
+error: consider moving the `;` outside the block for consistent formatting
+  --> tests/ui/semicolon_outside_block.rs:83:5
+   |
+LL | /     unsafe {
+LL | |         std::arch::asm!("");
+LL | |     }
+   | |_____^
+   |
+help: put the `;` here
+   |
+LL ~         std::arch::asm!("")
+LL ~     };
+   |
+
+error: consider moving the `;` outside the block for consistent formatting
+  --> tests/ui/semicolon_outside_block.rs:87:5
+   |
+LL | /     {
+LL | |         line!();
+LL | |     }
+   | |_____^
+   |
+help: put the `;` here
+   |
+LL ~         line!()
+LL ~     };
+   |
+
+error: aborting due to 6 previous errors