@@ -1094,29 +1094,49 @@ impl<'a, 'tcx> AssignmentResult<'a, 'tcx> {
10941094 self . body ,
10951095 ) ;
10961096
1097- // We probed MIR in reverse order for dataflow.
1098- // We revert the vector to give a consistent order to the user.
1099- for ( source_info, Access { live, kind, is_direct } ) in statements. into_iter ( ) . rev ( ) {
1097+ // By convention, underscore-prefixed bindings are allowed to be unused explicitly.
1098+ if name. as_str ( ) . starts_with ( '_' ) {
1099+ continue ;
1100+ }
1101+
1102+ let mut next_direct_assign = None ;
1103+ let mut dead_statements = Vec :: with_capacity ( statements. len ( ) ) ;
1104+
1105+ for ( source_info, Access { live, kind, is_direct } ) in statements. into_iter ( ) {
1106+ let overwrite = match ( kind, is_direct, next_direct_assign) {
1107+ ( AccessKind :: Assign , true , Some ( overwrite_span) ) => {
1108+ Some ( errors:: UnusedAssignOverwrite {
1109+ assigned_span : source_info. span ,
1110+ overwrite_span,
1111+ name,
1112+ } )
1113+ }
1114+ _ => None ,
1115+ } ;
1116+
1117+ if kind == AccessKind :: Assign && is_direct {
1118+ next_direct_assign = Some ( source_info. span ) ;
1119+ }
1120+
11001121 if live {
11011122 continue ;
11021123 }
1103-
11041124 // If this place was dropped and has non-trivial drop,
11051125 // skip reporting field assignments.
11061126 if !is_direct && is_maybe_drop_guard {
11071127 continue ;
11081128 }
1129+ dead_statements. push ( ( source_info, kind, is_direct, overwrite) ) ;
1130+ }
11091131
1132+ // We probed MIR in reverse order for dataflow.
1133+ // Emit diagnostics in source order instead.
1134+ for ( source_info, kind, is_direct, overwrite) in dead_statements. into_iter ( ) . rev ( ) {
11101135 // Report the dead assignment.
11111136 let Some ( hir_id) = source_info. scope . lint_root ( & self . body . source_scopes ) else {
11121137 continue ;
11131138 } ;
11141139
1115- // By convention, underscore-prefixed bindings are allowed to be unused explicitly
1116- if name. as_str ( ) . starts_with ( '_' ) {
1117- break ;
1118- }
1119-
11201140 match kind {
11211141 AccessKind :: Assign => {
11221142 let suggestion = annotate_mut_binding_to_immutable_binding (
@@ -1126,11 +1146,14 @@ impl<'a, 'tcx> AssignmentResult<'a, 'tcx> {
11261146 source_info. span ,
11271147 self . body ,
11281148 ) ;
1149+ let overwrite =
1150+ if suggestion. is_none ( ) && is_direct { overwrite } else { None } ;
1151+ let help = suggestion. is_none ( ) && overwrite. is_none ( ) ;
11291152 tcx. emit_node_span_lint (
11301153 lint:: builtin:: UNUSED_ASSIGNMENTS ,
11311154 hir_id,
11321155 source_info. span ,
1133- errors:: UnusedAssign { name, help : suggestion . is_none ( ) , suggestion } ,
1156+ errors:: UnusedAssign { name, overwrite , help , suggestion } ,
11341157 )
11351158 }
11361159 AccessKind :: Param => tcx. emit_node_span_lint (
0 commit comments