+/// Manually check for coercion casting by checking if the type of the match operand or let expr
+/// differs with the assigned local variable or the function return type.
+fn expr_ty_matches_p_ty(cx: &LateContext<'_>, expr: &Expr<'_>, p_expr: &Expr<'_>) -> bool {
+ if let Some(p_node) = get_parent_node(cx.tcx, p_expr.hir_id) {
+ match p_node {
+ // Compare match_expr ty with local in `let local = match match_expr {..}`
+ Node::Local(local) => {
+ let results = cx.typeck_results();
+ return same_type_and_consts(results.node_type(local.hir_id), results.expr_ty(expr));
+ },
+ // compare match_expr ty with RetTy in `fn foo() -> RetTy`
+ Node::Item(..) => {
+ if let Some(fn_decl) = p_node.fn_decl() {
+ if let FnRetTy::Return(ret_ty) = fn_decl.output {
+ return same_type_and_consts(hir_ty_to_ty(cx.tcx, ret_ty), cx.typeck_results().expr_ty(expr));
+ }
+ }
+ },
+ // check the parent expr for this whole block `{ match match_expr {..} }`
+ Node::Block(block) => {
+ if let Some(block_parent_expr) = get_parent_expr_for_hir(cx, block.hir_id) {
+ return expr_ty_matches_p_ty(cx, expr, block_parent_expr);
+ }
+ },
+ // recursively call on `if xxx {..}` etc.
+ Node::Expr(p_expr) => {
+ return expr_ty_matches_p_ty(cx, expr, p_expr);
+ },
+ _ => {},
+ }
+ }
+ false
+}
+