1
- use crate :: utils:: { match_def_path, paths, qpath_res, snippet, span_lint_and_note} ;
1
+ use crate :: utils:: { contains_name , match_def_path, paths, qpath_res, snippet, span_lint_and_note} ;
2
2
use if_chain:: if_chain;
3
3
use rustc_data_structures:: fx:: FxHashMap ;
4
4
use rustc_hir:: def:: Res ;
@@ -55,9 +55,10 @@ impl LateLintPass<'_> for FieldReassignWithDefault {
55
55
}
56
56
57
57
// find all "later statement"'s where the fields of the binding set as
58
- // Default::default() get reassigned
58
+ // Default::default() get reassigned, unless the reassignment refers to the original binding
59
59
let mut first_assign = None ;
60
60
let mut assigned_fields = FxHashMap :: default ( ) ;
61
+ let mut cancel_lint = false ;
61
62
for consecutive_statement in & block. stmts [ stmt_idx + 1 ..] {
62
63
// interrupt if the statement is a let binding (`Local`) that shadows the original
63
64
// binding
@@ -68,6 +69,12 @@ impl LateLintPass<'_> for FieldReassignWithDefault {
68
69
else if let Some ( ( field_ident, assign_rhs) ) =
69
70
field_reassigned_by_stmt ( consecutive_statement, binding_name)
70
71
{
72
+ // interrupt and cancel lint if assign_rhs references the original binding
73
+ if contains_name ( binding_name, assign_rhs) {
74
+ cancel_lint = true ;
75
+ break ;
76
+ }
77
+
71
78
// always re-insert set value, this way the latest value is stored for output snippet
72
79
assigned_fields. insert ( field_ident. name , assign_rhs) ;
73
80
@@ -84,7 +91,7 @@ impl LateLintPass<'_> for FieldReassignWithDefault {
84
91
85
92
// if there are incorrectly assigned fields, do a span_lint_and_note to suggest
86
93
// construction using `Ty { fields, ..Default::default() }`
87
- if !assigned_fields. is_empty ( ) {
94
+ if !assigned_fields. is_empty ( ) && !cancel_lint {
88
95
// take the original assignment as span
89
96
let stmt = & block. stmts [ stmt_idx] ;
90
97
0 commit comments