@@ -150,6 +150,59 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
150
150
}
151
151
}
152
152
153
+ fn check_for_self_assign ( & mut self , assign : & ' tcx hir:: Expr < ' tcx > ) {
154
+ fn check_for_self_assign_helper (
155
+ tcx : TyCtxt < ' tcx > ,
156
+ typeck_results : & ' tcx ty:: TypeckResults < ' tcx > ,
157
+ lhs : & ' tcx hir:: Expr < ' tcx > ,
158
+ rhs : & ' tcx hir:: Expr < ' tcx > ,
159
+ ) -> bool {
160
+ match ( & lhs. kind , & rhs. kind ) {
161
+ ( hir:: ExprKind :: Path ( ref qpath_l) , hir:: ExprKind :: Path ( ref qpath_r) ) => {
162
+ if let ( Res :: Local ( id_l) , Res :: Local ( id_r) ) = (
163
+ typeck_results. qpath_res ( qpath_l, lhs. hir_id ) ,
164
+ typeck_results. qpath_res ( qpath_r, rhs. hir_id ) ,
165
+ ) {
166
+ if id_l == id_r {
167
+ return true ;
168
+ }
169
+ }
170
+ return false ;
171
+ }
172
+ ( hir:: ExprKind :: Field ( lhs_l, ident_l) , hir:: ExprKind :: Field ( lhs_r, ident_r) ) => {
173
+ if ident_l == ident_r {
174
+ return check_for_self_assign_helper ( tcx, typeck_results, lhs_l, lhs_r) ;
175
+ }
176
+ return false ;
177
+ }
178
+ _ => {
179
+ return false ;
180
+ }
181
+ }
182
+ }
183
+
184
+ if let hir:: ExprKind :: Assign ( lhs, rhs, _) = assign. kind {
185
+ if check_for_self_assign_helper ( self . tcx , self . typeck_results ( ) , lhs, rhs)
186
+ && !assign. span . from_expansion ( )
187
+ {
188
+ let is_field_assign = matches ! ( lhs. kind, hir:: ExprKind :: Field ( ..) ) ;
189
+ self . tcx . struct_span_lint_hir (
190
+ lint:: builtin:: DEAD_CODE ,
191
+ assign. hir_id ,
192
+ assign. span ,
193
+ |lint| {
194
+ lint. build ( & format ! (
195
+ "useless assignment of {} of type `{}` to itself" ,
196
+ if is_field_assign { "field" } else { "variable" } ,
197
+ self . typeck_results( ) . expr_ty( lhs) ,
198
+ ) )
199
+ . emit ( ) ;
200
+ } ,
201
+ )
202
+ }
203
+ }
204
+ }
205
+
153
206
fn handle_field_pattern_match (
154
207
& mut self ,
155
208
lhs : & hir:: Pat < ' _ > ,
@@ -287,6 +340,7 @@ impl<'tcx> Visitor<'tcx> for MarkSymbolVisitor<'tcx> {
287
340
}
288
341
hir:: ExprKind :: Assign ( ref left, ref right, ..) => {
289
342
self . handle_assign ( left) ;
343
+ self . check_for_self_assign ( expr) ;
290
344
self . visit_expr ( right) ;
291
345
return ;
292
346
}
0 commit comments