@@ -132,7 +132,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for RedundantClone {
132
132
let pred_arg = if_chain ! {
133
133
if let Some ( ( pred_fn_def_id, pred_arg, pred_arg_ty, Some ( res) ) ) =
134
134
is_call_with_ref_arg( cx, mir, & pred_terminator. kind) ;
135
- if * res == mir:: Place :: Base ( mir :: PlaceBase :: Local ( cloned) ) ;
135
+ if res. base == mir:: PlaceBase :: Local ( cloned) ;
136
136
if match_def_path( cx, pred_fn_def_id, & paths:: DEREF_TRAIT_METHOD ) ;
137
137
if match_type( cx, pred_arg_ty, & paths:: PATH_BUF )
138
138
|| match_type( cx, pred_arg_ty, & paths:: OS_STRING ) ;
@@ -218,7 +218,7 @@ fn is_call_with_ref_arg<'tcx>(
218
218
if_chain ! {
219
219
if let TerminatorKind :: Call { func, args, destination, .. } = kind;
220
220
if args. len( ) == 1 ;
221
- if let mir:: Operand :: Move ( mir:: Place :: Base ( mir:: PlaceBase :: Local ( local) ) ) = & args[ 0 ] ;
221
+ if let mir:: Operand :: Move ( mir:: Place { base : mir:: PlaceBase :: Local ( local) , .. } ) = & args[ 0 ] ;
222
222
if let ty:: FnDef ( def_id, _) = func. ty( & * mir, cx. tcx) . sty;
223
223
if let ( inner_ty, 1 ) = walk_ptrs_ty_depth( args[ 0 ] . ty( & * mir, cx. tcx) ) ;
224
224
if !is_copy( cx, inner_ty) ;
@@ -244,7 +244,14 @@ fn find_stmt_assigns_to<'a, 'tcx: 'a>(
244
244
stmts
245
245
. rev ( )
246
246
. find_map ( |stmt| {
247
- if let mir:: StatementKind :: Assign ( mir:: Place :: Base ( mir:: PlaceBase :: Local ( local) ) , v) = & stmt. kind {
247
+ if let mir:: StatementKind :: Assign (
248
+ mir:: Place {
249
+ base : mir:: PlaceBase :: Local ( local) ,
250
+ ..
251
+ } ,
252
+ v,
253
+ ) = & stmt. kind
254
+ {
248
255
if * local == to {
249
256
return Some ( v) ;
250
257
}
@@ -271,28 +278,34 @@ fn find_stmt_assigns_to<'a, 'tcx: 'a>(
271
278
fn base_local_and_movability < ' tcx > (
272
279
cx : & LateContext < ' _ , ' tcx > ,
273
280
mir : & mir:: Body < ' tcx > ,
274
- mut place : & mir:: Place < ' tcx > ,
281
+ place : & mir:: Place < ' tcx > ,
275
282
) -> Option < ( mir:: Local , CannotMoveOut ) > {
276
- use rustc:: mir:: Place :: * ;
283
+ use rustc:: mir:: Place ;
277
284
use rustc:: mir:: PlaceBase ;
285
+ use rustc:: mir:: PlaceRef ;
286
+ use rustc:: mir:: Projection ;
278
287
279
288
// Dereference. You cannot move things out from a borrowed value.
280
289
let mut deref = false ;
281
290
// Accessing a field of an ADT that has `Drop`. Moving the field out will cause E0509.
282
291
let mut field = false ;
283
292
284
- loop {
285
- match place {
286
- Base ( PlaceBase :: Local ( local ) ) => return Some ( ( * local , deref || field ) ) ,
287
- Projection ( proj ) => {
288
- place = & proj . base ;
289
- deref = deref || matches ! ( proj . elem , mir :: ProjectionElem :: Deref ) ;
290
- if !field && matches ! ( proj . elem , mir :: ProjectionElem :: Field ( .. ) ) {
291
- field = has_drop ( cx , place . ty ( & mir. local_decls , cx . tcx ) . ty ) ;
292
- }
293
- } ,
294
- _ => return None ,
293
+ let PlaceRef {
294
+ base : place_base ,
295
+ mut projection ,
296
+ } = place . as_place_ref ( ) ;
297
+ if let PlaceBase :: Local ( local ) = place_base {
298
+ while let Some ( box Projection { base , elem } ) = projection {
299
+ projection = base ;
300
+ deref = matches ! ( elem , mir:: ProjectionElem :: Deref ) ;
301
+ field = !field
302
+ && matches ! ( elem , mir :: ProjectionElem :: Field ( .. ) )
303
+ && has_drop ( cx , Place :: ty_from ( place_base , projection , & mir . local_decls , cx . tcx ) . ty ) ;
295
304
}
305
+
306
+ Some ( ( * local, deref || field) )
307
+ } else {
308
+ None
296
309
}
297
310
}
298
311
0 commit comments