]> git.lizzy.rs Git - rust.git/blob - clippy_lints/src/matches/infalliable_detructuring_match.rs
Split out `infalliable_detructuring_match`
[rust.git] / clippy_lints / src / matches / infalliable_detructuring_match.rs
1 use clippy_utils::diagnostics::span_lint_and_sugg;
2 use clippy_utils::source::snippet_with_applicability;
3 use clippy_utils::{path_to_local_id, peel_blocks, strip_pat_refs};
4 use rustc_errors::Applicability;
5 use rustc_hir::{ExprKind, Local, MatchSource, PatKind, QPath};
6 use rustc_lint::LateContext;
7
8 use super::INFALLIBLE_DESTRUCTURING_MATCH;
9
10 pub(crate) fn check(cx: &LateContext<'_>, local: &Local<'_>) -> bool {
11     if_chain! {
12         if !local.span.from_expansion();
13         if let Some(expr) = local.init;
14         if let ExprKind::Match(target, arms, MatchSource::Normal) = expr.kind;
15         if arms.len() == 1 && arms[0].guard.is_none();
16         if let PatKind::TupleStruct(
17             QPath::Resolved(None, variant_name), args, _) = arms[0].pat.kind;
18         if args.len() == 1;
19         if let PatKind::Binding(_, arg, ..) = strip_pat_refs(&args[0]).kind;
20         let body = peel_blocks(arms[0].body);
21         if path_to_local_id(body, arg);
22
23         then {
24             let mut applicability = Applicability::MachineApplicable;
25             span_lint_and_sugg(
26                 cx,
27                 INFALLIBLE_DESTRUCTURING_MATCH,
28                 local.span,
29                 "you seem to be trying to use `match` to destructure a single infallible pattern. \
30                 Consider using `let`",
31                 "try this",
32                 format!(
33                     "let {}({}) = {};",
34                     snippet_with_applicability(cx, variant_name.span, "..", &mut applicability),
35                     snippet_with_applicability(cx, local.pat.span, "..", &mut applicability),
36                     snippet_with_applicability(cx, target.span, "..", &mut applicability),
37                 ),
38                 applicability,
39             );
40             return true;
41         }
42     }
43     false
44 }