Enhance semicolon_if_nothing_returned according to #7324

This commit is contained in:
Bastian Kersting 2021-06-05 14:27:36 +02:00
parent e4a1e8524c
commit 96747c1a46
4 changed files with 80 additions and 3 deletions

View file

@ -1,9 +1,9 @@
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::source::snippet_with_macro_callsite;
use clippy_utils::{in_macro, sugg};
use clippy_utils::{get_parent_expr_for_hir, in_macro, spans_on_same_line, sugg};
use if_chain::if_chain;
use rustc_errors::Applicability;
use rustc_hir::{Block, ExprKind};
use rustc_hir::{Block, BlockCheckMode, ExprKind};
use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint};
@ -46,6 +46,22 @@ impl LateLintPass<'_> for SemicolonIfNothingReturned {
if let snippet = snippet_with_macro_callsite(cx, expr.span, "}");
if !snippet.ends_with('}');
then {
// check if the block is inside a closure or an unsafe block and don't
// emit if the block is on the same line
if_chain! {
if let Some(parent) = get_parent_expr_for_hir(cx, block.hir_id);
if !matches!(block.rules, BlockCheckMode::DefaultBlock) ||
matches!(parent.kind, ExprKind::Closure(..) | ExprKind::Block(..));
if block.stmts.len() == 0;
if spans_on_same_line(cx, parent.span, expr.span);
then {
return;
}
}
// filter out the desugared `for` loop
if let ExprKind::DropTemps(..) = &expr.kind {
return;

View file

@ -820,6 +820,11 @@ fn line_span<T: LintContext>(cx: &T, span: Span) -> Span {
Span::new(line_start, span.hi(), span.ctxt())
}
/// Checks if two spans begin on the same line.
pub fn spans_on_same_line<T: LintContext>(cx: &T, left_span: Span, right_span: Span) -> bool {
line_span(cx, left_span).lo() == line_span(cx, right_span).lo()
}
/// Gets the parent node, if any.
pub fn get_parent_node(tcx: TyCtxt<'_>, id: HirId) -> Option<Node<'_>> {
tcx.hir().parent_iter(id).next().map(|(_, node)| node)

View file

@ -17,6 +17,24 @@ fn basic101(x: i32) {
y = x + 1
}
#[rustfmt::skip]
fn closure_error() {
let _d = || {
hello()
};
}
#[rustfmt::skip]
fn unsafe_checks_error() {
use std::mem::MaybeUninit;
use std::ptr;
let mut s = MaybeUninit::<String>::uninit();
let _d = || unsafe {
ptr::drop_in_place(s.as_mut_ptr())
};
}
// this is fine
fn print_sum(a: i32, b: i32) {
println!("{}", a + b);
@ -53,3 +71,29 @@ fn loop_test(x: i32) {
println!("{}", ext);
}
}
fn closure() {
let _d = || hello();
}
#[rustfmt::skip]
fn closure_block() {
let _d = || { hello() };
}
unsafe fn some_unsafe_op() {}
unsafe fn some_other_unsafe_fn() {}
fn do_something() {
unsafe { some_unsafe_op() };
unsafe { some_other_unsafe_fn() };
}
fn unsafe_checks() {
use std::mem::MaybeUninit;
use std::ptr;
let mut s = MaybeUninit::<String>::uninit();
let _d = || unsafe { ptr::drop_in_place(s.as_mut_ptr()) };
}

View file

@ -18,5 +18,17 @@ error: consider adding a `;` to the last statement for consistent formatting
LL | y = x + 1
| ^^^^^^^^^ help: add a `;` here: `y = x + 1;`
error: aborting due to 3 previous errors
error: consider adding a `;` to the last statement for consistent formatting
--> $DIR/semicolon_if_nothing_returned.rs:23:9
|
LL | hello()
| ^^^^^^^ help: add a `;` here: `hello();`
error: consider adding a `;` to the last statement for consistent formatting
--> $DIR/semicolon_if_nothing_returned.rs:34:9
|
LL | ptr::drop_in_place(s.as_mut_ptr())
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: add a `;` here: `ptr::drop_in_place(s.as_mut_ptr());`
error: aborting due to 5 previous errors