|
1 | 1 | use clippy_utils::diagnostics::span_lint_and_help; |
| 2 | +use clippy_utils::path_def_id; |
2 | 3 | use clippy_utils::source::snippet; |
3 | | -use rustc_ast::Expr; |
4 | | -use rustc_ast::ast::{ExprKind, StructRest}; |
5 | | -use rustc_lint::{EarlyContext, EarlyLintPass, LintContext}; |
| 4 | +use rustc_hir::{ExprKind, StructTailExpr}; |
| 5 | +use rustc_lint::{LateLintPass, LintContext}; |
6 | 6 | use rustc_session::declare_lint_pass; |
| 7 | +use rustc_span::sym; |
7 | 8 |
|
8 | 9 | declare_clippy_lint! { |
9 | 10 | /// ### What it does |
10 | | - /// Check struct initialization uses `..base` pattern to skip rest of struct field initialization. |
| 11 | + /// Check struct initialization uses `..*::default()` pattern to skip rest of struct field initialization. |
11 | 12 | /// |
12 | 13 | /// ### Why restrict this? |
13 | | - /// Using `..base` can hide field initialization when new fields are added to structs, |
| 14 | + /// Using `..*::default()` can hide field initialization when new fields are added to structs, |
14 | 15 | /// potentially leading to bugs where developers forget to explicitly set values for new fields. |
15 | 16 | /// |
16 | 17 | /// ### Example |
@@ -54,11 +55,13 @@ declare_clippy_lint! { |
54 | 55 |
|
55 | 56 | declare_lint_pass!(StructFieldsDefault => [STRUCT_FIELDS_REST_DEFAULT]); |
56 | 57 |
|
57 | | -impl EarlyLintPass for StructFieldsDefault { |
58 | | - fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) { |
| 58 | +impl<'tcx> LateLintPass<'tcx> for StructFieldsDefault { |
| 59 | + fn check_expr(&mut self, cx: &rustc_lint::LateContext<'tcx>, expr: &'tcx rustc_hir::Expr<'tcx>) { |
59 | 60 | if !expr.span.in_external_macro(cx.sess().source_map()) |
60 | | - && let ExprKind::Struct(struct_expr) = &expr.kind |
61 | | - && let StructRest::Base(base) = &struct_expr.rest |
| 61 | + && let ExprKind::Struct(_, _, StructTailExpr::Base(base)) = &expr.kind |
| 62 | + && let ExprKind::Call(func, _) = base.kind |
| 63 | + && let Some(did) = path_def_id(cx, func) |
| 64 | + && cx.tcx.is_diagnostic_item(sym::default_fn, did) |
62 | 65 | { |
63 | 66 | span_lint_and_help( |
64 | 67 | cx, |
|
0 commit comments