pub fn extract_assert_macro_args<'tcx>(e: &'tcx Expr<'tcx>) -> Option<Vec<&'tcx Expr<'tcx>>> {
    /// Try to match the AST for a pattern that contains a match, for example when two args are
    /// compared
    fn ast_matchblock(matchblock_expr: &'tcx Expr<'tcx>) -> Option<Vec<&Expr<'_>>> {
        if_chain! {
            if let ExprKind::Match(headerexpr, _, _) = &matchblock_expr.kind;
            if let ExprKind::Tup([lhs, rhs]) = &headerexpr.kind;
            if let ExprKind::AddrOf(BorrowKind::Ref, _, lhs) = lhs.kind;
            if let ExprKind::AddrOf(BorrowKind::Ref, _, rhs) = rhs.kind;
            then {
                return Some(vec![lhs, rhs]);
            }
        }
        None
    }

    if let ExprKind::Block(block, _) = e.kind {
        if block.stmts.len() == 1 {
            if let StmtKind::Semi(matchexpr) = block.stmts.get(0)?.kind {
                // macros with unique arg: `{debug_}assert!` (e.g., `debug_assert!(some_condition)`)
                if_chain! {
                    if let ExprKind::If(clause, _, _)  = matchexpr.kind;
                    if let ExprKind::Unary(UnOp::Not, condition) = clause.kind;
                    then {
                        return Some(vec![condition]);
                    }
                }

                // debug macros with two args: `debug_assert_{ne, eq}` (e.g., `assert_ne!(a, b)`)
                if_chain! {
                    if let ExprKind::Block(matchblock,_) = matchexpr.kind;
                    if let Some(matchblock_expr) = matchblock.expr;
                    then {
                        return ast_matchblock(matchblock_expr);
                    }
                }
            }
        } else if let Some(matchblock_expr) = block.expr {
            // macros with two args: `assert_{ne, eq}` (e.g., `assert_ne!(a, b)`)
            return ast_matchblock(matchblock_expr);
        }
    }
    None
}
/// Extract args from an assert-like macro.
/// Currently working with:
/// - `assert!`, `assert_eq!` and `assert_ne!`
/// - `debug_assert!`, `debug_assert_eq!` and `debug_assert_ne!`
/// For example:
/// `assert!(expr)` will return Some([expr])
/// `debug_assert_eq!(a, b)` will return Some([a, b])
Extract args from an assert-like macro.
Extract args from an assert - like macro .
pub fn extract_assert_macro_args<'tcx>(e: &'tcx Expr<'tcx>) -> Option<Vec<&'tcx Expr<'tcx>>> {
    /// Try to match the AST for a pattern that contains a match, for example when two args are
    /// compared
    fn ast_matchblock(matchblock_expr: &'tcx Expr<'tcx>) -> Option<Vec<&Expr<'_>>> {
        if_chain! {
            if let ExprKind::Match(headerexpr, _, _) = &matchblock_expr.kind;
            if let ExprKind::Tup([lhs, rhs]) = &headerexpr.kind;
            if let ExprKind::AddrOf(BorrowKind::Ref, _, lhs) = lhs.kind;
            if let ExprKind::AddrOf(BorrowKind::Ref, _, rhs) = rhs.kind;
            then {
                return Some(vec![lhs, rhs]);
            }
        }
        None
    }
    if let ExprKind::Block(block, _) = e.kind {
        if block.stmts.len() == 1 {
            if let StmtKind::Semi(matchexpr) = block.stmts.get(0)?.kind {
                // macros with unique arg: `{debug_}assert!` (e.g., `debug_assert!(some_condition)`)
                if_chain! {
                    if let ExprKind::If(clause, _, _)  = matchexpr.kind;
                    if let ExprKind::Unary(UnOp::Not, condition) = clause.kind;
                    then {
                        return Some(vec![condition]);
                    }
                }
                // debug macros with two args: `debug_assert_{ne, eq}` (e.g., `assert_ne!(a, b)`)
                if_chain! {
                    if let ExprKind::Block(matchblock,_) = matchexpr.kind;
                    if let Some(matchblock_expr) = matchblock.expr;
                    then {
                        return ast_matchblock(matchblock_expr);
                    }
                }
            }
        } else if let Some(matchblock_expr) = block.expr {
            // macros with two args: `assert_{ne, eq}` (e.g., `assert_ne!(a, b)`)
            return ast_matchblock(matchblock_expr);
        }
    }
    None
}
pub fn extract_assert_macro_args < ' tcx > ( e : & ' tcx Expr < ' tcx > ) -> Option < Vec < & ' tcx Expr < ' tcx > > > { /// Try to match the AST for a pattern that contains a match, for example when two args are /// compared fn ast_matchblock ( matchblock_expr : & ' tcx Expr < ' tcx > ) -> Option < Vec < & Expr < ' _ > > > { if_chain ! { if let ExprKind Match ( headerexpr ) matchblock_expr kind if let ExprKind Tup ( [ lhs rhs ] ) headerexpr kind if let ExprKind AddrOf ( BorrowKind Ref lhs ) lhs kind if let ExprKind AddrOf ( BorrowKind Ref rhs ) rhs kind then { return Some ( vec [ lhs rhs ] ) } } None } if let ExprKind :: Block ( block , _ ) = e . kind { if block . stmts . len ( ) == 1 { if let StmtKind :: Semi ( matchexpr ) = block . stmts . get ( 0 ) ? . kind { // macros with unique arg: `{debug_}assert!` (e.g., `debug_assert!(some_condition)`) if_chain ! { if let ExprKind If ( clause ) matchexpr kind if let ExprKind Unary ( UnOp Not condition ) clause kind then { return Some ( vec [ condition ] ) } } // debug macros with two args: `debug_assert_{ne, eq}` (e.g., `assert_ne!(a, b)`) if_chain ! { if let ExprKind Block ( matchblock ) matchexpr kind if let Some ( matchblock_expr ) matchblock expr then { return ast_matchblock ( matchblock_expr ) } } } } else if let Some ( matchblock_expr ) = block . expr { // macros with two args: `assert_{ne, eq}` (e.g., `assert_ne!(a, b)`) return ast_matchblock ( matchblock_expr ) ; } } None }
Extract args from an assert-like macro.
Extract args from an assert - like macro .
e
&'tcx Expr<'tcx>
e
&'tcx Expr<'tcx>