| use clippy_config::msrvs::{self, Msrv}; |
| use clippy_utils::diagnostics::span_lint_and_sugg; |
| use rustc_ast::ast::{Expr, ExprKind}; |
| use rustc_errors::Applicability; |
| use rustc_lint::{EarlyContext, EarlyLintPass, LintContext}; |
| use rustc_middle::lint::in_external_macro; |
| use rustc_session::impl_lint_pass; |
| |
| declare_clippy_lint! { |
| /// ### What it does |
| /// Checks for fields in struct literals where shorthands |
| /// could be used. |
| /// |
| /// ### Why is this bad? |
| /// If the field and variable names are the same, |
| /// the field name is redundant. |
| /// |
| /// ### Example |
| /// ```no_run |
| /// let bar: u8 = 123; |
| /// |
| /// struct Foo { |
| /// bar: u8, |
| /// } |
| /// |
| /// let foo = Foo { bar: bar }; |
| /// ``` |
| /// the last line can be simplified to |
| /// ```ignore |
| /// let foo = Foo { bar }; |
| /// ``` |
| #[clippy::version = "pre 1.29.0"] |
| pub REDUNDANT_FIELD_NAMES, |
| style, |
| "checks for fields in struct literals where shorthands could be used" |
| } |
| |
| pub struct RedundantFieldNames { |
| msrv: Msrv, |
| } |
| |
| impl RedundantFieldNames { |
| #[must_use] |
| pub fn new(msrv: Msrv) -> Self { |
| Self { msrv } |
| } |
| } |
| |
| impl_lint_pass!(RedundantFieldNames => [REDUNDANT_FIELD_NAMES]); |
| |
| impl EarlyLintPass for RedundantFieldNames { |
| fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) { |
| if !self.msrv.meets(msrvs::FIELD_INIT_SHORTHAND) { |
| return; |
| } |
| |
| if in_external_macro(cx.sess(), expr.span) { |
| return; |
| } |
| if let ExprKind::Struct(ref se) = expr.kind { |
| for field in &se.fields { |
| if !field.is_shorthand |
| && let ExprKind::Path(None, path) = &field.expr.kind |
| && let [segment] = path.segments.as_slice() |
| && segment.args.is_none() |
| && segment.ident == field.ident |
| && field.span.eq_ctxt(field.ident.span) |
| { |
| span_lint_and_sugg( |
| cx, |
| REDUNDANT_FIELD_NAMES, |
| field.span, |
| "redundant field names in struct initialization", |
| "replace it with", |
| field.ident.to_string(), |
| Applicability::MachineApplicable, |
| ); |
| } |
| } |
| } |
| } |
| extract_msrv_attr!(EarlyContext); |
| } |