@@ -132,7 +132,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for RedundantClone {
132132 let pred_arg = if_chain ! {
133133 if let Some ( ( pred_fn_def_id, pred_arg, pred_arg_ty, Some ( res) ) ) =
134134 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) ;
136136 if match_def_path( cx, pred_fn_def_id, & paths:: DEREF_TRAIT_METHOD ) ;
137137 if match_type( cx, pred_arg_ty, & paths:: PATH_BUF )
138138 || match_type( cx, pred_arg_ty, & paths:: OS_STRING ) ;
@@ -218,7 +218,7 @@ fn is_call_with_ref_arg<'tcx>(
218218 if_chain ! {
219219 if let TerminatorKind :: Call { func, args, destination, .. } = kind;
220220 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 ] ;
222222 if let ty:: FnDef ( def_id, _) = func. ty( & * mir, cx. tcx) . sty;
223223 if let ( inner_ty, 1 ) = walk_ptrs_ty_depth( args[ 0 ] . ty( & * mir, cx. tcx) ) ;
224224 if !is_copy( cx, inner_ty) ;
@@ -244,7 +244,14 @@ fn find_stmt_assigns_to<'a, 'tcx: 'a>(
244244 stmts
245245 . rev ( )
246246 . 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+ {
248255 if * local == to {
249256 return Some ( v) ;
250257 }
@@ -271,28 +278,34 @@ fn find_stmt_assigns_to<'a, 'tcx: 'a>(
271278fn base_local_and_movability < ' tcx > (
272279 cx : & LateContext < ' _ , ' tcx > ,
273280 mir : & mir:: Body < ' tcx > ,
274- mut place : & mir:: Place < ' tcx > ,
281+ place : & mir:: Place < ' tcx > ,
275282) -> Option < ( mir:: Local , CannotMoveOut ) > {
276- use rustc:: mir:: Place :: * ;
283+ use rustc:: mir:: Place ;
277284 use rustc:: mir:: PlaceBase ;
285+ use rustc:: mir:: PlaceRef ;
286+ use rustc:: mir:: Projection ;
278287
279288 // Dereference. You cannot move things out from a borrowed value.
280289 let mut deref = false ;
281290 // Accessing a field of an ADT that has `Drop`. Moving the field out will cause E0509.
282291 let mut field = false ;
283292
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 ) ;
295304 }
305+
306+ Some ( ( * local, deref || field) )
307+ } else {
308+ None
296309 }
297310}
298311
0 commit comments