]> git.lizzy.rs Git - rust.git/blob - src/tools/clippy/clippy_lints/src/misc_early/unneeded_field_pattern.rs
Merge commit '9809f5d21990d9e24b3e9876ea7da756fd4e9def' into libgccjit-codegen
[rust.git] / src / tools / clippy / clippy_lints / src / misc_early / unneeded_field_pattern.rs
1 use clippy_utils::diagnostics::{span_lint, span_lint_and_help};
2 use rustc_ast::ast::{Pat, PatKind};
3 use rustc_lint::{EarlyContext, LintContext};
4
5 use super::UNNEEDED_FIELD_PATTERN;
6
7 pub(super) fn check(cx: &EarlyContext<'_>, pat: &Pat) {
8     if let PatKind::Struct(_, ref npat, ref pfields, _) = pat.kind {
9         let mut wilds = 0;
10         let type_name = npat
11             .segments
12             .last()
13             .expect("A path must have at least one segment")
14             .ident
15             .name;
16
17         for field in pfields {
18             if let PatKind::Wild = field.pat.kind {
19                 wilds += 1;
20             }
21         }
22         if !pfields.is_empty() && wilds == pfields.len() {
23             span_lint_and_help(
24                 cx,
25                 UNNEEDED_FIELD_PATTERN,
26                 pat.span,
27                 "all the struct fields are matched to a wildcard pattern, consider using `..`",
28                 None,
29                 &format!("try with `{} {{ .. }}` instead", type_name),
30             );
31             return;
32         }
33         if wilds > 0 {
34             for field in pfields {
35                 if let PatKind::Wild = field.pat.kind {
36                     wilds -= 1;
37                     if wilds > 0 {
38                         span_lint(
39                             cx,
40                             UNNEEDED_FIELD_PATTERN,
41                             field.span,
42                             "you matched a field with a wildcard pattern, consider using `..` instead",
43                         );
44                     } else {
45                         let mut normal = vec![];
46
47                         for field in pfields {
48                             match field.pat.kind {
49                                 PatKind::Wild => {},
50                                 _ => {
51                                     if let Ok(n) = cx.sess().source_map().span_to_snippet(field.span) {
52                                         normal.push(n);
53                                     }
54                                 },
55                             }
56                         }
57
58                         span_lint_and_help(
59                             cx,
60                             UNNEEDED_FIELD_PATTERN,
61                             field.span,
62                             "you matched a field with a wildcard pattern, consider using `..` \
63                              instead",
64                             None,
65                             &format!("try with `{} {{ {}, .. }}`", type_name, normal[..].join(", ")),
66                         );
67                     }
68                 }
69             }
70         }
71     }
72 }