2 use rustc::{declare_lint, lint_array};
4 use crate::utils::{in_macro, is_range_expression, match_var, span_lint_and_sugg};
6 /// **What it does:** Checks for fields in struct literals where shorthands
9 /// **Why is this bad?** If the field and variable names are the same,
10 /// the field name is redundant.
12 /// **Known problems:** None.
16 /// let bar: u8 = 123;
22 /// let foo = Foo{ bar: bar }
24 declare_clippy_lint! {
25 pub REDUNDANT_FIELD_NAMES,
27 "checks for fields in struct literals where shorthands could be used"
30 pub struct RedundantFieldNames;
32 impl LintPass for RedundantFieldNames {
33 fn get_lints(&self) -> LintArray {
34 lint_array!(REDUNDANT_FIELD_NAMES)
38 impl<'a, 'tcx> LateLintPass<'a, 'tcx> for RedundantFieldNames {
39 fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) {
40 // Ignore all macros including range expressions.
41 // They can have redundant field names when expanded.
42 // e.g. range expression `start..end` is desugared to `Range { start: start, end: end }`
43 if in_macro(expr.span) || is_range_expression(expr.span) {
47 if let ExprKind::Struct(_, ref fields, _) = expr.node {
49 let name = field.ident.name;
51 if match_var(&field.expr, name) && !field.is_shorthand {
54 REDUNDANT_FIELD_NAMES,
56 "redundant field names in struct initialization",