Skip to content

Commit 66ab580

Browse files
author
Henri Lunnikivi
committed
Switch to LateLintPass
1 parent d75d37c commit 66ab580

File tree

2 files changed

+25
-22
lines changed

2 files changed

+25
-22
lines changed

clippy_lints/src/field_reassign_with_default.rs

+24-21
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1-
use crate::utils::{match_path_ast, paths, snippet, span_lint_and_note};
1+
use crate::utils::{match_def_path, paths, qpath_res, snippet, span_lint_and_note};
22
use if_chain::if_chain;
3-
use rustc_ast::ast::{Block, ExprKind, PatKind, StmtKind};
4-
use rustc_lint::{EarlyContext, EarlyLintPass};
5-
use rustc_session::{declare_lint_pass, declare_tool_lint};
3+
use rustc_hir::def::Res;
4+
use rustc_hir::{Block, ExprKind, PatKind, QPath, StmtKind};
65
use rustc_span::symbol::Symbol;
76

7+
use rustc_lint::{LateContext, LateLintPass};
8+
use rustc_session::{declare_lint_pass, declare_tool_lint};
9+
810
declare_clippy_lint! {
911
/// **What it does:** Checks for immediate reassignment of fields initialized
1012
/// with Default::default().
@@ -13,19 +15,18 @@ declare_clippy_lint! {
1315
/// T { field: value, ..Default::default() } syntax instead of using a mutable binding.
1416
///
1517
/// **Known problems:** The lint does not detect calls to Default::default()
16-
/// if they are made via another struct implementing the Default trait. This
17-
/// may be corrected with a LateLintPass. If type inference stops requiring
18-
/// an explicit type for assignment using Default::default() this lint will
19-
/// not trigger for cases where the type is elided. This may also be corrected
20-
/// with a LateLintPass.
18+
/// if they are made via another struct implementing the Default trait. If type inference stops
19+
/// requiring an explicit type for assignment using Default::default() this lint will not
20+
/// trigger for cases where the type is elided.
2121
///
2222
/// **Example:**
23+
/// Bad:
2324
/// ```ignore
24-
/// // Bad
2525
/// let mut a: A = Default::default();
2626
/// a.i = 42;
27-
///
28-
/// // Good
27+
/// ```
28+
/// Use instead:
29+
/// ```ignore
2930
/// let a = A {
3031
/// i: 42,
3132
/// .. Default::default()
@@ -38,8 +39,8 @@ declare_clippy_lint! {
3839

3940
declare_lint_pass!(FieldReassignWithDefault => [FIELD_REASSIGN_WITH_DEFAULT]);
4041

41-
impl EarlyLintPass for FieldReassignWithDefault {
42-
fn check_block(&mut self, cx: &EarlyContext<'_>, block: &Block) {
42+
impl LateLintPass<'_> for FieldReassignWithDefault {
43+
fn check_block(&mut self, cx: &LateContext<'_>, block: &Block<'_>) {
4344
// store statement index and name of binding for all statements like
4445
// `let mut binding = Default::default();`
4546
let binding_statements_using_default: Vec<(usize, Symbol)> = block
@@ -51,15 +52,16 @@ impl EarlyLintPass for FieldReassignWithDefault {
5152
// only take `let ...` statements
5253
if let StmtKind::Local(ref local) = stmt.kind;
5354
// only take bindings to identifiers
54-
if let PatKind::Ident(_, binding, _) = local.pat.kind;
55+
if let PatKind::Binding(_, _, ident, _) = local.pat.kind;
5556
// only when assigning `... = Default::default()`
5657
if let Some(ref expr) = local.init;
5758
if let ExprKind::Call(ref fn_expr, _) = &expr.kind;
58-
if let ExprKind::Path( _, path ) = &fn_expr.kind;
59+
if let ExprKind::Path( qpath ) = &fn_expr.kind;
60+
if let Res::Def(_, def_id) = qpath_res(cx, qpath, fn_expr.hir_id);
5961
// right hand side of assignment is `Default::default`
60-
if match_path_ast(&path, &paths::DEFAULT_TRAIT_METHOD);
62+
if match_def_path(cx, def_id, &paths::DEFAULT_TRAIT_METHOD);
6163
then {
62-
Some((idx, binding.name))
64+
Some((idx, ident.name))
6365
}
6466
else {
6567
None
@@ -84,8 +86,8 @@ impl EarlyLintPass for FieldReassignWithDefault {
8486
// interrupt if the statement is a let binding (`Local`) that shadows the original
8587
// binding
8688
if let StmtKind::Local(local) = &post_defassign_stmt.kind {
87-
if let PatKind::Ident(_, id, _) = local.pat.kind {
88-
if id.name == binding_name {
89+
if let PatKind::Binding(_, _, ident, _) = local.pat.kind {
90+
if ident.name == binding_name {
8991
break;
9092
}
9193
}
@@ -100,7 +102,8 @@ impl EarlyLintPass for FieldReassignWithDefault {
100102
// only take assignments to fields where the left-hand side field is a field of
101103
// the same binding as the previous statement
102104
if let ExprKind::Field(ref binding, later_field_ident) = assign_lhs.kind;
103-
if let ExprKind::Path( _, ref path ) = binding.kind;
105+
if let ExprKind::Path(ref qpath) = binding.kind;
106+
if let QPath::Resolved(_, path) = qpath;
104107
if let Some(second_binding_name) = path.segments.last();
105108
if second_binding_name.ident.name == binding_name;
106109
then {

clippy_lints/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1058,7 +1058,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
10581058
let enum_variant_name_threshold = conf.enum_variant_name_threshold;
10591059
store.register_early_pass(move || box enum_variants::EnumVariantNames::new(enum_variant_name_threshold));
10601060
store.register_early_pass(|| box tabs_in_doc_comments::TabsInDocComments);
1061-
store.register_early_pass(|| box field_reassign_with_default::FieldReassignWithDefault);
1061+
store.register_late_pass(|| box field_reassign_with_default::FieldReassignWithDefault);
10621062
store.register_late_pass(|| box unused_self::UnusedSelf);
10631063
store.register_late_pass(|| box mutable_debug_assertion::DebugAssertWithMutCall);
10641064
store.register_late_pass(|| box exit::Exit);

0 commit comments

Comments
 (0)