1 use super::manual_utils::{check_with, SomeExpr};
3 use clippy_utils::diagnostics::span_lint_and_sugg;
5 use clippy_utils::{is_res_lang_ctor, path_res};
7 use rustc_hir::LangItem::OptionSome;
8 use rustc_hir::{Arm, Block, BlockCheckMode, Expr, ExprKind, Pat, UnsafeSource};
9 use rustc_lint::LateContext;
10 use rustc_span::SyntaxContext;
12 pub(super) fn check_match<'tcx>(
13 cx: &LateContext<'tcx>,
15 scrutinee: &'tcx Expr<'_>,
16 arms: &'tcx [Arm<'_>],
18 if let [arm1, arm2] = arms
19 && arm1.guard.is_none()
20 && arm2.guard.is_none()
22 check(cx, expr, scrutinee, arm1.pat, arm1.body, Some(arm2.pat), arm2.body);
26 pub(super) fn check_if_let<'tcx>(
27 cx: &LateContext<'tcx>,
29 let_pat: &'tcx Pat<'_>,
30 let_expr: &'tcx Expr<'_>,
31 then_expr: &'tcx Expr<'_>,
32 else_expr: &'tcx Expr<'_>,
34 check(cx, expr, let_expr, let_pat, then_expr, None, else_expr);
38 cx: &LateContext<'tcx>,
40 scrutinee: &'tcx Expr<'_>,
41 then_pat: &'tcx Pat<'_>,
42 then_body: &'tcx Expr<'_>,
43 else_pat: Option<&'tcx Pat<'_>>,
44 else_body: &'tcx Expr<'_>,
46 if let Some(sugg_info) = check_with(
60 "manual implementation of `Option::map`",
62 if sugg_info.needs_brackets {
65 sugg_info.scrutinee_str, sugg_info.as_ref_str, sugg_info.body_str
70 sugg_info.scrutinee_str, sugg_info.as_ref_str, sugg_info.body_str
78 // Checks for an expression wrapped by the `Some` constructor. Returns the contained expression.
79 fn get_some_expr<'tcx>(
80 cx: &LateContext<'tcx>,
84 ) -> Option<SomeExpr<'tcx>> {
85 fn get_some_expr_internal<'tcx>(
86 cx: &LateContext<'tcx>,
88 needs_unsafe_block: bool,
90 ) -> Option<SomeExpr<'tcx>> {
91 // TODO: Allow more complex expressions.
93 ExprKind::Call(callee, [arg])
94 if ctxt == expr.span.ctxt() && is_res_lang_ctor(cx, path_res(cx, callee), OptionSome) =>
96 Some(SomeExpr::new_no_negated(arg, needs_unsafe_block))
106 ) => get_some_expr_internal(
109 needs_unsafe_block || *rules == BlockCheckMode::UnsafeBlock(UnsafeSource::UserProvided),
115 get_some_expr_internal(cx, expr, false, ctxt)