Skip to content

Commit aa108f6

Browse files
committed
Enhance semicolon_if_nothing_returned according to #7324
1 parent 9991040 commit aa108f6

File tree

4 files changed

+80
-3
lines changed

4 files changed

+80
-3
lines changed

clippy_lints/src/semicolon_if_nothing_returned.rs

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
use clippy_utils::diagnostics::span_lint_and_sugg;
22
use clippy_utils::source::snippet_with_macro_callsite;
3-
use clippy_utils::{in_macro, sugg};
3+
use clippy_utils::{get_parent_expr_for_hir, in_macro, spans_on_same_line, sugg};
44
use if_chain::if_chain;
55
use rustc_errors::Applicability;
6-
use rustc_hir::{Block, ExprKind};
6+
use rustc_hir::{Block, BlockCheckMode, ExprKind};
77
use rustc_lint::{LateContext, LateLintPass};
88
use rustc_session::{declare_lint_pass, declare_tool_lint};
99

@@ -46,6 +46,22 @@ impl LateLintPass<'_> for SemicolonIfNothingReturned {
4646
if let snippet = snippet_with_macro_callsite(cx, expr.span, "}");
4747
if !snippet.ends_with('}');
4848
then {
49+
// check if the block is inside a closure or an unsafe block and don't
50+
// emit if the block is on the same line
51+
if_chain! {
52+
if let Some(parent) = get_parent_expr_for_hir(cx, block.hir_id);
53+
54+
if !matches!(block.rules, BlockCheckMode::DefaultBlock) ||
55+
matches!(parent.kind, ExprKind::Closure(..) | ExprKind::Block(..));
56+
57+
if block.stmts.len() == 0;
58+
59+
if spans_on_same_line(cx, parent.span, expr.span);
60+
then {
61+
return;
62+
}
63+
}
64+
4965
// filter out the desugared `for` loop
5066
if let ExprKind::DropTemps(..) = &expr.kind {
5167
return;

clippy_utils/src/lib.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -820,6 +820,11 @@ fn line_span<T: LintContext>(cx: &T, span: Span) -> Span {
820820
Span::new(line_start, span.hi(), span.ctxt())
821821
}
822822

823+
/// Checks if two spans begin on the same line.
824+
pub fn spans_on_same_line<T: LintContext>(cx: &T, left_span: Span, right_span: Span) -> bool {
825+
line_span(cx, left_span).lo() == line_span(cx, right_span).lo()
826+
}
827+
823828
/// Gets the parent node, if any.
824829
pub fn get_parent_node(tcx: TyCtxt<'_>, id: HirId) -> Option<Node<'_>> {
825830
tcx.hir().parent_iter(id).next().map(|(_, node)| node)

tests/ui/semicolon_if_nothing_returned.rs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,24 @@ fn basic101(x: i32) {
1717
y = x + 1
1818
}
1919

20+
#[rustfmt::skip]
21+
fn closure_error() {
22+
let _d = || {
23+
hello()
24+
};
25+
}
26+
27+
#[rustfmt::skip]
28+
fn unsafe_checks_error() {
29+
use std::mem::MaybeUninit;
30+
use std::ptr;
31+
32+
let mut s = MaybeUninit::<String>::uninit();
33+
let _d = || unsafe {
34+
ptr::drop_in_place(s.as_mut_ptr())
35+
};
36+
}
37+
2038
// this is fine
2139
fn print_sum(a: i32, b: i32) {
2240
println!("{}", a + b);
@@ -53,3 +71,29 @@ fn loop_test(x: i32) {
5371
println!("{}", ext);
5472
}
5573
}
74+
75+
fn closure() {
76+
let _d = || hello();
77+
}
78+
79+
#[rustfmt::skip]
80+
fn closure_block() {
81+
let _d = || { hello() };
82+
}
83+
84+
unsafe fn some_unsafe_op() {}
85+
unsafe fn some_other_unsafe_fn() {}
86+
87+
fn do_something() {
88+
unsafe { some_unsafe_op() };
89+
90+
unsafe { some_other_unsafe_fn() };
91+
}
92+
93+
fn unsafe_checks() {
94+
use std::mem::MaybeUninit;
95+
use std::ptr;
96+
97+
let mut s = MaybeUninit::<String>::uninit();
98+
let _d = || unsafe { ptr::drop_in_place(s.as_mut_ptr()) };
99+
}

tests/ui/semicolon_if_nothing_returned.stderr

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,17 @@ error: consider adding a `;` to the last statement for consistent formatting
1818
LL | y = x + 1
1919
| ^^^^^^^^^ help: add a `;` here: `y = x + 1;`
2020

21-
error: aborting due to 3 previous errors
21+
error: consider adding a `;` to the last statement for consistent formatting
22+
--> $DIR/semicolon_if_nothing_returned.rs:23:9
23+
|
24+
LL | hello()
25+
| ^^^^^^^ help: add a `;` here: `hello();`
26+
27+
error: consider adding a `;` to the last statement for consistent formatting
28+
--> $DIR/semicolon_if_nothing_returned.rs:34:9
29+
|
30+
LL | ptr::drop_in_place(s.as_mut_ptr())
31+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: add a `;` here: `ptr::drop_in_place(s.as_mut_ptr());`
32+
33+
error: aborting due to 5 previous errors
2234

0 commit comments

Comments
 (0)