]> git.lizzy.rs Git - rust.git/blob - clippy_lints/src/redundant_field_names.rs
Auto merge of #3597 - xfix:match-ergonomics, r=phansch
[rust.git] / clippy_lints / src / redundant_field_names.rs
1 // Copyright 2014-2018 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution.
3 //
4 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
5 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
6 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
7 // option. This file may not be copied, modified, or distributed
8 // except according to those terms.
9
10 use crate::utils::span_lint_and_sugg;
11 use rustc::lint::{EarlyContext, EarlyLintPass, LintArray, LintPass};
12 use rustc::{declare_tool_lint, lint_array};
13 use rustc_errors::Applicability;
14 use syntax::ast::*;
15
16 /// **What it does:** Checks for fields in struct literals where shorthands
17 /// could be used.
18 ///
19 /// **Why is this bad?** If the field and variable names are the same,
20 /// the field name is redundant.
21 ///
22 /// **Known problems:** None.
23 ///
24 /// **Example:**
25 /// ```rust
26 /// let bar: u8 = 123;
27 ///
28 /// struct Foo {
29 ///     bar: u8,
30 /// }
31 ///
32 /// let foo = Foo{ bar: bar }
33 /// ```
34 /// the last line can be simplified to
35 /// ```rust
36 /// let foo = Foo{ bar }
37 /// ```
38 declare_clippy_lint! {
39     pub REDUNDANT_FIELD_NAMES,
40     style,
41     "checks for fields in struct literals where shorthands could be used"
42 }
43
44 pub struct RedundantFieldNames;
45
46 impl LintPass for RedundantFieldNames {
47     fn get_lints(&self) -> LintArray {
48         lint_array!(REDUNDANT_FIELD_NAMES)
49     }
50 }
51
52 impl EarlyLintPass for RedundantFieldNames {
53     fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) {
54         if let ExprKind::Struct(_, ref fields, _) = expr.node {
55             for field in fields {
56                 if field.is_shorthand {
57                     continue;
58                 }
59                 if let ExprKind::Path(None, path) = &field.expr.node {
60                     if path.segments.len() == 1
61                         && path.segments[0].ident == field.ident
62                         && path.segments[0].args.is_none()
63                     {
64                         span_lint_and_sugg(
65                             cx,
66                             REDUNDANT_FIELD_NAMES,
67                             field.span,
68                             "redundant field names in struct initialization",
69                             "replace it with",
70                             field.ident.to_string(),
71                             Applicability::MachineApplicable,
72                         );
73                     }
74                 }
75             }
76         }
77     }
78 }