]> git.lizzy.rs Git - rust.git/blobdiff - clippy_lints/src/redundant_clone.rs
Fix breakage due to rust-lang/rust#60913
[rust.git] / clippy_lints / src / redundant_clone.rs
index db25b74cd0815194250a4589364bf8667e31f9cf..d24a20b079d1d64c683f63f2fc0e23417cae6531 100644 (file)
@@ -1,6 +1,6 @@
 use crate::utils::{
-    has_drop, in_macro, is_copy, match_type, paths, snippet_opt, span_lint_hir, span_lint_hir_and_then,
-    walk_ptrs_ty_depth,
+    has_drop, in_macro_or_desugar, is_copy, match_def_path, match_type, paths, snippet_opt, span_lint_hir,
+    span_lint_hir_and_then, walk_ptrs_ty_depth,
 };
 use if_chain::if_chain;
 use matches::matches;
@@ -83,7 +83,7 @@ fn check_fn(
         for (bb, bbdata) in mir.basic_blocks().iter_enumerated() {
             let terminator = bbdata.terminator();
 
-            if in_macro(terminator.source_info.span) {
+            if in_macro_or_desugar(terminator.source_info.span) {
                 continue;
             }
 
@@ -94,13 +94,13 @@ fn check_fn(
 
             let (fn_def_id, arg, arg_ty, _) = unwrap_or_continue!(is_call_with_ref_arg(cx, mir, &terminator.kind));
 
-            let from_borrow = cx.match_def_path(fn_def_id, &paths::CLONE_TRAIT_METHOD)
-                || cx.match_def_path(fn_def_id, &paths::TO_OWNED_METHOD)
-                || (cx.match_def_path(fn_def_id, &paths::TO_STRING_METHOD) && match_type(cx, arg_ty, &paths::STRING));
+            let from_borrow = match_def_path(cx, fn_def_id, &paths::CLONE_TRAIT_METHOD)
+                || match_def_path(cx, fn_def_id, &paths::TO_OWNED_METHOD)
+                || (match_def_path(cx, fn_def_id, &paths::TO_STRING_METHOD) && match_type(cx, arg_ty, &paths::STRING));
 
             let from_deref = !from_borrow
-                && (cx.match_def_path(fn_def_id, &paths::PATH_TO_PATH_BUF)
-                    || cx.match_def_path(fn_def_id, &paths::OS_STR_TO_OS_STRING));
+                && (match_def_path(cx, fn_def_id, &paths::PATH_TO_PATH_BUF)
+                    || match_def_path(cx, fn_def_id, &paths::OS_STR_TO_OS_STRING));
 
             if !from_borrow && !from_deref {
                 continue;
@@ -132,8 +132,8 @@ fn check_fn(
                 let pred_arg = if_chain! {
                     if let Some((pred_fn_def_id, pred_arg, pred_arg_ty, Some(res))) =
                         is_call_with_ref_arg(cx, mir, &pred_terminator.kind);
-                    if *res == mir::Place::Base(mir::PlaceBase::Local(cloned));
-                    if cx.match_def_path(pred_fn_def_id, &paths::DEREF_TRAIT_METHOD);
+                    if res.base == mir::PlaceBase::Local(cloned);
+                    if match_def_path(cx, pred_fn_def_id, &paths::DEREF_TRAIT_METHOD);
                     if match_type(cx, pred_arg_ty, &paths::PATH_BUF)
                         || match_type(cx, pred_arg_ty, &paths::OS_STRING);
                     then {
@@ -212,13 +212,13 @@ fn check_fn(
 /// If `kind` is `y = func(x: &T)` where `T: !Copy`, returns `(DefId of func, x, T, y)`.
 fn is_call_with_ref_arg<'tcx>(
     cx: &LateContext<'_, 'tcx>,
-    mir: &'tcx mir::Mir<'tcx>,
+    mir: &'tcx mir::Body<'tcx>,
     kind: &'tcx mir::TerminatorKind<'tcx>,
 ) -> Option<(def_id::DefId, mir::Local, Ty<'tcx>, Option<&'tcx mir::Place<'tcx>>)> {
     if_chain! {
         if let TerminatorKind::Call { func, args, destination, .. } = kind;
         if args.len() == 1;
-        if let mir::Operand::Move(mir::Place::Base(mir::PlaceBase::Local(local))) = &args[0];
+        if let mir::Operand::Move(mir::Place { base: mir::PlaceBase::Local(local), .. }) = &args[0];
         if let ty::FnDef(def_id, _) = func.ty(&*mir, cx.tcx).sty;
         if let (inner_ty, 1) = walk_ptrs_ty_depth(args[0].ty(&*mir, cx.tcx));
         if !is_copy(cx, inner_ty);
@@ -236,7 +236,7 @@ fn is_call_with_ref_arg<'tcx>(
 /// ``Some((from, [`true` if `from` cannot be moved out]))``.
 fn find_stmt_assigns_to<'a, 'tcx: 'a>(
     cx: &LateContext<'_, 'tcx>,
-    mir: &mir::Mir<'tcx>,
+    mir: &mir::Body<'tcx>,
     to: mir::Local,
     by_ref: bool,
     stmts: impl DoubleEndedIterator<Item = &'a mir::Statement<'tcx>>,
@@ -244,7 +244,14 @@ fn find_stmt_assigns_to<'a, 'tcx: 'a>(
     stmts
         .rev()
         .find_map(|stmt| {
-            if let mir::StatementKind::Assign(mir::Place::Base(mir::PlaceBase::Local(local)), v) = &stmt.kind {
+            if let mir::StatementKind::Assign(
+                mir::Place {
+                    base: mir::PlaceBase::Local(local),
+                    ..
+                },
+                v,
+            ) = &stmt.kind
+            {
                 if *local == to {
                     return Some(v);
                 }
@@ -270,29 +277,35 @@ fn find_stmt_assigns_to<'a, 'tcx: 'a>(
 /// Also reports whether given `place` cannot be moved out.
 fn base_local_and_movability<'tcx>(
     cx: &LateContext<'_, 'tcx>,
-    mir: &mir::Mir<'tcx>,
-    mut place: &mir::Place<'tcx>,
+    mir: &mir::Body<'tcx>,
+    place: &mir::Place<'tcx>,
 ) -> Option<(mir::Local, CannotMoveOut)> {
-    use rustc::mir::Place::*;
+    use rustc::mir::Place;
     use rustc::mir::PlaceBase;
+    use rustc::mir::PlaceRef;
+    use rustc::mir::Projection;
 
     // Dereference. You cannot move things out from a borrowed value.
     let mut deref = false;
     // Accessing a field of an ADT that has `Drop`. Moving the field out will cause E0509.
     let mut field = false;
 
-    loop {
-        match place {
-            Base(PlaceBase::Local(local)) => return Some((*local, deref || field)),
-            Projection(proj) => {
-                place = &proj.base;
-                deref = deref || matches!(proj.elem, mir::ProjectionElem::Deref);
-                if !field && matches!(proj.elem, mir::ProjectionElem::Field(..)) {
-                    field = has_drop(cx, place.ty(&mir.local_decls, cx.tcx).ty);
-                }
-            },
-            _ => return None,
+    let PlaceRef {
+        base: place_base,
+        mut projection,
+    } = place.as_place_ref();
+    if let PlaceBase::Local(local) = place_base {
+        while let Some(box Projection { base, elem }) = projection {
+            projection = base;
+            deref = matches!(elem, mir::ProjectionElem::Deref);
+            field = !field
+                && matches!(elem, mir::ProjectionElem::Field(..))
+                && has_drop(cx, Place::ty_from(place_base, projection, &mir.local_decls, cx.tcx).ty);
         }
+
+        Some((*local, deref || field))
+    } else {
+        None
     }
 }