/// Convert a boolean expression to a boolean for use in && or || or if
Convert a boolean expression to a boolean for use in && or || or if
Convert a boolean expression to a boolean for use in && or || or if
fn match_bool(&self, target: bool, ty_id: CTypeId, val: P<Expr>) -> P<Expr> {
        let ty = &self.ast_context.resolve_type(ty_id).kind;
        if self.ast_context.is_function_pointer(ty_id) {
            if target {
                mk().method_call_expr(val, "is_some", vec![] as Vec<P<Expr>>)
            } else {
                mk().method_call_expr(val, "is_none", vec![] as Vec<P<Expr>>)
            }
        } else if ty.is_pointer() {
            let mut res = mk().method_call_expr(val, "is_null", vec![] as Vec<P<Expr>>);
            if target {
                res = mk().unary_expr(ast::UnOp::Not, res)
            }
            res
        } else if ty.is_bool() {
            if target {
                val
            } else {
                mk().unary_expr(ast::UnOp::Not, val)
            }
        } else {
            let zero = if ty.is_floating_type() {
                mk().lit_expr(mk().float_unsuffixed_lit("0."))
            } else {
                mk().lit_expr(mk().int_lit(0, LitIntType::Unsuffixed))
            };
            // One simplification we can make at the cost of inspecting `val` more closely: if `val`
            // is already in the form `(x <op> y) as <ty>` where `<op>` is a Rust operator
            // that returns a boolean, we can simple output `x <op> y` or `!(x <op> y)`.
            if let ExprKind::Cast(ref arg, _) = val.node {
                if let ExprKind::Binary(op, _, _) = arg.node {
                    match op.node {
                        BinOpKind::Or | BinOpKind::And |
                        BinOpKind::Eq | BinOpKind::Ne |
                        BinOpKind::Lt | BinOpKind::Le |
                        BinOpKind::Gt | BinOpKind::Ge => if target {
                            // If target == true, just return the argument
                            return arg.clone();
                        } else {
                            // If target == false, return !arg
                            return mk().unary_expr(ast::UnOp::Not, arg.clone());
                        },
                        _ => {}
                    }
                }
            }
            let val = if ty.is_enum() { mk().cast_expr(val, mk().path_ty(vec!["u64"])) } else { val };
            // The backup is to just compare against zero
            if target {
                mk().binary_expr(BinOpKind::Ne, zero, val)
            } else {
                mk().binary_expr(BinOpKind::Eq, zero, val)
            }
        }
    }
fn match_bool ( & self , target : bool , ty_id : CTypeId , val : P < Expr > ) -> P < Expr > { let ty = & self . ast_context . resolve_type ( ty_id ) . kind ; if self . ast_context . is_function_pointer ( ty_id ) { if target { mk ( ) . method_call_expr ( val , " " , vec ! [ ] as Vec < P < Expr > > ) } else { mk ( ) . method_call_expr ( val , " " , vec ! [ ] as Vec < P < Expr > > ) } } else if ty . is_pointer ( ) { let mut res = mk ( ) . method_call_expr ( val , " " , vec ! [ ] as Vec < P < Expr > > ) ; if target { res = mk ( ) . unary_expr ( ast :: UnOp :: Not , res ) } res } else if ty . is_bool ( ) { if target { val } else { mk ( ) . unary_expr ( ast :: UnOp :: Not , val ) } } else { let zero = if ty . is_floating_type ( ) { mk ( ) . lit_expr ( mk ( ) . float_unsuffixed_lit ( " " ) ) } else { mk ( ) . lit_expr ( mk ( ) . int_lit ( 0 , LitIntType :: Unsuffixed ) ) } ; // One simplification we can make at the cost of inspecting `val` more closely: if `val` // is already in the form `(x <op> y) as <ty>` where `<op>` is a Rust operator // that returns a boolean, we can simple output `x <op> y` or `!(x <op> y)`. if let ExprKind :: Cast ( ref arg , _ ) = val . node { if let ExprKind :: Binary ( op , _ , _ ) = arg . node { match op . node { BinOpKind :: Or | BinOpKind :: And | BinOpKind :: Eq | BinOpKind :: Ne | BinOpKind :: Lt | BinOpKind :: Le | BinOpKind :: Gt | BinOpKind :: Ge => if target { // If target == true, just return the argument return arg . clone ( ) ; } else { // If target == false, return !arg return mk ( ) . unary_expr ( ast :: UnOp :: Not , arg . clone ( ) ) ; } , _ => { } } } } let val = if ty . is_enum ( ) { mk ( ) . cast_expr ( val , mk ( ) . path_ty ( vec ! [ " " ] ) ) } else { val } ; // The backup is to just compare against zero if target { mk ( ) . binary_expr ( BinOpKind :: Ne , zero , val ) } else { mk ( ) . binary_expr ( BinOpKind :: Eq , zero , val ) } } }
Convert a boolean expression to a boolean for use in && or || or if
Convert a boolean expression to a boolean for use in && or || or if
&self
target
bool
ty_id
CTypeId
val
P<Expr>