[manual_assert]: Preserve comments in the suggestion

This commit is contained in:
kraktus 2022-09-14 11:58:41 +02:00
parent 5d837b58f7
commit 2c04c1a188
7 changed files with 237 additions and 51 deletions

View file

@ -1,9 +1,10 @@
use clippy_utils::diagnostics::span_lint_and_sugg;
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::{peel_blocks_with_stmt, sugg};
use clippy_utils::{peel_blocks_with_stmt, span_extract_comment, sugg};
use rustc_errors::Applicability;
use rustc_hir::{Expr, ExprKind, UnOp};
use rustc_hir::{Expr, ExprKind};
use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::sym;
@ -50,20 +51,33 @@ impl<'tcx> LateLintPass<'tcx> for ManualAssert {
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 (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});");
span_lint_and_sugg(
let mut comments = span_extract_comment(cx.sess().source_map(), expr.span);
if !comments.is_empty() {
comments += "\n";
}
// we need to negate the <cond> expression because `assert!` panics when <cond> is `false`, wherease original pattern panicked when evaluating to `true`
let cond_sugg = !sugg::Sugg::hir_with_applicability(cx, cond, "..", &mut applicability);
let sugg = format!("assert!({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",
"try",
sugg,
Applicability::MachineApplicable,
|diag| {
// comments can be noisy, do not show them to the user
diag.tool_only_span_suggestion(
expr.span.shrink_to_lo(),
"add comments back",
comments,
applicability);
diag.span_suggestion(
expr.span,
"try instead",
sugg,
applicability);
}
);
}
}