summaryrefslogtreecommitdiffstats
path: root/src/tools/clippy/clippy_lints/src/manual_assert.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/tools/clippy/clippy_lints/src/manual_assert.rs')
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_assert.rs97
1 files changed, 48 insertions, 49 deletions
diff --git a/src/tools/clippy/clippy_lints/src/manual_assert.rs b/src/tools/clippy/clippy_lints/src/manual_assert.rs
index 4277455a3..ce5d657bc 100644
--- a/src/tools/clippy/clippy_lints/src/manual_assert.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_assert.rs
@@ -1,7 +1,6 @@
use crate::rustc_lint::LintContext;
use clippy_utils::diagnostics::span_lint_and_then;
-use clippy_utils::macros::{root_macro_call, FormatArgsExpn};
-use clippy_utils::source::snippet_with_applicability;
+use clippy_utils::macros::root_macro_call;
use clippy_utils::{is_else_clause, peel_blocks_with_stmt, span_extract_comment, sugg};
use rustc_errors::Applicability;
use rustc_hir::{Expr, ExprKind, UnOp};
@@ -38,57 +37,57 @@ declare_lint_pass!(ManualAssert => [MANUAL_ASSERT]);
impl<'tcx> LateLintPass<'tcx> for ManualAssert {
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &Expr<'tcx>) {
- if_chain! {
- if let ExprKind::If(cond, then, None) = expr.kind;
- if !matches!(cond.kind, ExprKind::Let(_));
- if !expr.span.from_expansion();
- let then = peel_blocks_with_stmt(then);
- if let Some(macro_call) = root_macro_call(then.span);
- if cx.tcx.item_name(macro_call.def_id) == sym::panic;
- if !cx.tcx.sess.source_map().is_multiline(cond.span);
- if let Some(format_args) = FormatArgsExpn::find_nested(cx, then, macro_call.expn);
+ if let ExprKind::If(cond, then, None) = expr.kind
+ && !matches!(cond.kind, ExprKind::Let(_))
+ && !expr.span.from_expansion()
+ && let then = peel_blocks_with_stmt(then)
+ && let Some(macro_call) = root_macro_call(then.span)
+ && cx.tcx.item_name(macro_call.def_id) == sym::panic
+ && !cx.tcx.sess.source_map().is_multiline(cond.span)
+ && let Ok(panic_snippet) = cx.sess().source_map().span_to_snippet(macro_call.span)
+ && let Some(panic_snippet) = panic_snippet.strip_suffix(')')
+ && let Some((_, format_args_snip)) = panic_snippet.split_once('(')
// Don't change `else if foo { panic!(..) }` to `else { assert!(foo, ..) }` as it just
// shuffles the condition around.
// Should this have a config value?
- if !is_else_clause(cx.tcx, expr);
- then {
- let mut applicability = Applicability::MachineApplicable;
- let format_args_snip = snippet_with_applicability(cx, format_args.inputs_span(), "..", &mut applicability);
- let cond = cond.peel_drop_temps();
- let mut comments = span_extract_comment(cx.sess().source_map(), expr.span);
- if !comments.is_empty() {
- comments += "\n";
- }
- let (cond, not) = match cond.kind {
- ExprKind::Unary(UnOp::Not, e) => (e, ""),
- _ => (cond, "!"),
- };
- let cond_sugg = sugg::Sugg::hir_with_applicability(cx, cond, "..", &mut applicability).maybe_par();
- let sugg = format!("assert!({not}{cond_sugg}, {format_args_snip});");
- // we show to the user the suggestion without the comments, but when applicating the fix, include the comments in the block
- span_lint_and_then(
- cx,
- MANUAL_ASSERT,
- expr.span,
- "only a `panic!` in `if`-then statement",
- |diag| {
- // comments can be noisy, do not show them to the user
- if !comments.is_empty() {
- diag.tool_only_span_suggestion(
- expr.span.shrink_to_lo(),
- "add comments back",
- comments,
- applicability);
- }
- diag.span_suggestion(
- expr.span,
- "try instead",
- sugg,
- applicability);
- }
-
- );
+ && !is_else_clause(cx.tcx, expr)
+ {
+ let mut applicability = Applicability::MachineApplicable;
+ let cond = cond.peel_drop_temps();
+ let mut comments = span_extract_comment(cx.sess().source_map(), expr.span);
+ if !comments.is_empty() {
+ comments += "\n";
}
+ let (cond, not) = match cond.kind {
+ ExprKind::Unary(UnOp::Not, e) => (e, ""),
+ _ => (cond, "!"),
+ };
+ let cond_sugg = sugg::Sugg::hir_with_applicability(cx, cond, "..", &mut applicability).maybe_par();
+ let sugg = format!("assert!({not}{cond_sugg}, {format_args_snip});");
+ // we show to the user the suggestion without the comments, but when applicating the fix, include the comments in the block
+ span_lint_and_then(
+ cx,
+ MANUAL_ASSERT,
+ expr.span,
+ "only a `panic!` in `if`-then statement",
+ |diag| {
+ // comments can be noisy, do not show them to the user
+ if !comments.is_empty() {
+ diag.tool_only_span_suggestion(
+ expr.span.shrink_to_lo(),
+ "add comments back",
+ comments,
+ applicability
+ );
+ }
+ diag.span_suggestion(
+ expr.span,
+ "try instead",
+ sugg,
+ applicability
+ );
+ }
+ );
}
}
}