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} ;
22use if_chain:: if_chain;
33use rustc_data_structures:: fx:: FxHashMap ;
44use rustc_hir:: def:: Res ;
@@ -55,9 +55,10 @@ impl LateLintPass<'_> for FieldReassignWithDefault {
5555 }
5656
5757 // 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
5959 let mut first_assign = None ;
6060 let mut assigned_fields = FxHashMap :: default ( ) ;
61+ let mut cancel_lint = false ;
6162 for consecutive_statement in & block. stmts [ stmt_idx + 1 ..] {
6263 // interrupt if the statement is a let binding (`Local`) that shadows the original
6364 // binding
@@ -68,6 +69,12 @@ impl LateLintPass<'_> for FieldReassignWithDefault {
6869 else if let Some ( ( field_ident, assign_rhs) ) =
6970 field_reassigned_by_stmt ( consecutive_statement, binding_name)
7071 {
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+
7178 // always re-insert set value, this way the latest value is stored for output snippet
7279 assigned_fields. insert ( field_ident. name , assign_rhs) ;
7380
@@ -84,7 +91,7 @@ impl LateLintPass<'_> for FieldReassignWithDefault {
8491
8592 // if there are incorrectly assigned fields, do a span_lint_and_note to suggest
8693 // construction using `Ty { fields, ..Default::default() }`
87- if !assigned_fields. is_empty ( ) {
94+ if !assigned_fields. is_empty ( ) && !cancel_lint {
8895 // take the original assignment as span
8996 let stmt = & block. stmts [ stmt_idx] ;
9097
0 commit comments