Skip to content

Commit 8c48a75

Browse files
committed
change based on review and debug_assert
1 parent fdf76ba commit 8c48a75

File tree

1 file changed

+49
-48
lines changed

1 file changed

+49
-48
lines changed

clippy_utils/src/higher.rs

+49-48
Original file line numberDiff line numberDiff line change
@@ -421,18 +421,25 @@ pub fn binop(op: hir::BinOpKind) -> ast::BinOpKind {
421421
}
422422
}
423423

424+
/// Kind of assert macros
425+
pub enum AssertExpnKind<'tcx> {
426+
/// Boolean macro like `assert!` or `debug_assert!`
427+
Bool(&'tcx Expr<'tcx>),
428+
/// Comparaison maacro like `assert_eq!`, `assert_ne!`, `debug_assert_eq!` or `debug_assert_ne!`
429+
Eq(&'tcx Expr<'tcx>, &'tcx Expr<'tcx>),
430+
}
431+
424432
/// A parsed
425433
/// `assert!`, `assert_eq!` or `assert_ne!`,
426434
/// `debug_assert!`, `debug_assert_eq!` or `debug_assert_ne!`
427435
/// macro.
428436
pub struct AssertExpn<'tcx> {
429-
/// the first agrument of the assret e.g. `var` in element `assert!(var, ...)`
430-
pub first_assert_argument: &'tcx Expr<'tcx>,
431-
/// second argument of the asset for case `assert_eq!`,
432-
/// `assert_ne!` etc ... Eg var_2 in `debug_assert_eq!(x, var_2,..)`
433-
pub second_assert_argument: Option<&'tcx Expr<'tcx>>,
437+
/// Kind of assert macro
438+
pub kind: AssertExpnKind<'tcx>,
434439
/// The format argument passed at the end of the macro
435440
pub format_arg: Option<FormatArgsExpn<'tcx>>,
441+
/// is a debug macro
442+
pub is_debug: bool,
436443
}
437444

438445
impl<'tcx> AssertExpn<'tcx> {
@@ -445,39 +452,38 @@ impl<'tcx> AssertExpn<'tcx> {
445452
/// second_assert_argument: None, format_arg:None })` `debug_assert_eq!(a, b)` will return
446453
/// `Some(AssertExpn { first_assert_argument: a, second_assert_argument: Some(b),
447454
/// format_arg:None })`
455+
/// FIXME assert!
448456
pub fn parse(e: &'tcx Expr<'tcx>) -> Option<Self> {
449457
if let ExprKind::Block(block, _) = e.kind {
450458
if block.stmts.len() == 1 {
451459
if let StmtKind::Semi(matchexpr) = block.stmts.get(0)?.kind {
452-
// macros with unique arg: `{debug_}assert!` (e.g., `debug_assert!(some_condition)`)
460+
// debug macros with unique arg: `debug_assert!` (e.g., `debug_assert!(some_condition)`)
453461
if_chain! {
454462
if let Some(If { cond, then, .. }) = If::hir(matchexpr);
455463
if let ExprKind::Unary(UnOp::Not, condition) = cond.kind;
456464
then {
457465
if_chain! {
458466
if let ExprKind::Block(block, _) = then.kind;
459-
if let [statement, ..] = block.stmts;
460-
if let StmtKind::Expr(call_assert_failed)
461-
| StmtKind::Semi(call_assert_failed) = statement.kind;
462-
if let ExprKind::Call(_, args_assert_failed) = call_assert_failed.kind;
463-
if !args_assert_failed.is_empty();
464-
if let ExprKind::Call(_, [arg, ..]) = args_assert_failed[0].kind;
467+
if let Some(begin_panic_fmt_block) = block.expr;
468+
if let ExprKind::Block(block,_) = begin_panic_fmt_block.kind;
469+
if let Some(expr) = block.expr;
470+
if let ExprKind::Call(_, args_begin_panic_fmt) = expr.kind;
471+
if !args_begin_panic_fmt.is_empty();
472+
if let ExprKind::AddrOf(_, _, arg) = args_begin_panic_fmt[0].kind;
465473
if let Some(format_arg_expn) = FormatArgsExpn::parse(arg);
466474
then {
467475
return Some(Self {
468-
first_assert_argument: condition,
469-
second_assert_argument: None,
470-
format_arg: Some(format_arg_expn), // FIXME actually parse the aguments
471-
});
472-
}
473-
else{
474-
return Some(Self {
475-
first_assert_argument: condition,
476-
second_assert_argument: None,
477-
format_arg: None,
476+
kind: AssertExpnKind::Bool(condition),
477+
format_arg: Some(format_arg_expn),
478+
is_debug: true,
478479
});
479480
}
480481
}
482+
return Some(Self {
483+
kind: AssertExpnKind::Bool(condition),
484+
format_arg: None,
485+
is_debug: true,
486+
});
481487
}
482488
}
483489

@@ -486,21 +492,21 @@ impl<'tcx> AssertExpn<'tcx> {
486492
if let ExprKind::Block(matchblock,_) = matchexpr.kind;
487493
if let Some(matchblock_expr) = matchblock.expr;
488494
then {
489-
return Self::ast_matchblock(matchblock_expr);
495+
return Self::ast_matchblock(matchblock_expr, true);
490496
}
491497
}
492498
}
493499
} else if let Some(matchblock_expr) = block.expr {
494500
// macros with two args: `assert_{ne, eq}` (e.g., `assert_ne!(a, b)`)
495-
return Self::ast_matchblock(matchblock_expr);
501+
return Self::ast_matchblock(matchblock_expr, false);
496502
}
497503
}
498504
None
499505
}
500506

501507
/// Try to match the AST for a pattern that contains a match, for example when two args are
502508
/// compared
503-
fn ast_matchblock(matchblock_expr: &'tcx Expr<'tcx>) -> Option<Self> {
509+
fn ast_matchblock(matchblock_expr: &'tcx Expr<'tcx>, is_debug: bool) -> Option<Self> {
504510
if_chain! {
505511
if let ExprKind::Match(headerexpr, arms, _) = &matchblock_expr.kind;
506512
if let ExprKind::Tup([lhs, rhs]) = &headerexpr.kind;
@@ -521,32 +527,32 @@ impl<'tcx> AssertExpn<'tcx> {
521527
if let Some(format_arg_expn) = FormatArgsExpn::parse(arg);
522528
then {
523529
return Some(AssertExpn {
524-
first_assert_argument: lhs,
525-
second_assert_argument: Some(rhs),
526-
format_arg: Some(format_arg_expn)
527-
});
528-
}
529-
else {
530-
return Some(AssertExpn {
531-
first_assert_argument: lhs,
532-
second_assert_argument:
533-
Some(rhs),
534-
format_arg: None
530+
kind: AssertExpnKind::Eq(lhs,rhs),
531+
format_arg: Some(format_arg_expn),
532+
is_debug,
535533
});
536534
}
537535
}
536+
return Some(AssertExpn {
537+
kind: AssertExpnKind::Eq(lhs,rhs),
538+
format_arg: None,
539+
is_debug,
540+
});
538541
}
539542
}
540543
None
541544
}
542545

543546
/// Gives the argument in the comparaison as a vector leaving the format
544547
pub fn assert_arguments(&self) -> Vec<&'tcx Expr<'tcx>> {
545-
let mut expr_vec = vec![self.first_assert_argument];
546-
if let Some(sec_agr) = self.second_assert_argument {
547-
expr_vec.push(sec_agr);
548+
match self.kind {
549+
AssertExpnKind::Bool(expr) => {
550+
vec![expr]
551+
},
552+
AssertExpnKind::Eq(lhs, rhs) => {
553+
vec![lhs, rhs]
554+
},
548555
}
549-
expr_vec
550556
}
551557

552558
/// Gives the argument passed to the macro as a string
@@ -555,14 +561,9 @@ impl<'tcx> AssertExpn<'tcx> {
555561
cx: &LateContext<'_>,
556562
applicability: &mut Applicability,
557563
) -> Vec<Cow<'static, str>> {
558-
let mut vec_arg = vec![snippet_with_applicability(
559-
cx,
560-
self.first_assert_argument.span,
561-
"..",
562-
applicability,
563-
)];
564-
if let Some(sec_agr) = self.second_assert_argument {
565-
vec_arg.push(snippet_with_applicability(cx, sec_agr.span, "..", applicability));
564+
let mut vec_arg = vec![];
565+
for arg in self.assert_arguments() {
566+
vec_arg.push(snippet_with_applicability(cx, arg.span, "..", applicability));
566567
}
567568
vec_arg.append(&mut self.format_arguments(cx, applicability));
568569
vec_arg

0 commit comments

Comments
 (0)