Skip to content

Commit

Permalink
remove the semicolon for builtin macro call statements in `statement_…
Browse files Browse the repository at this point in the history
…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
  • Loading branch information
y21 committed Oct 20, 2024
1 parent 4de65a1 commit 65eb1ec
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 13 deletions.
27 changes: 15 additions & 12 deletions clippy_lints/src/semicolon_block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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), .. }, _),
Expand Down
8 changes: 8 additions & 0 deletions tests/ui/semicolon_outside_block.fixed
Original file line number Diff line number Diff line change
Expand Up @@ -80,5 +80,13 @@ fn main() {

{ unit_fn_block(); };

unsafe {
std::arch::asm!("")
};

{
line!()
};

unit_fn_block()
}
8 changes: 8 additions & 0 deletions tests/ui/semicolon_outside_block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,5 +80,13 @@ fn main() {

{ unit_fn_block(); };

unsafe {
std::arch::asm!("");
}

{
line!();
}

unit_fn_block()
}
30 changes: 29 additions & 1 deletion tests/ui/semicolon_outside_block.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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

0 comments on commit 65eb1ec

Please sign in to comment.