about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--clippy_lints/src/lib.rs3
-rw-r--r--clippy_lints/src/redundant_clone.rs45
-rw-r--r--clippy_lints/src/utils/internal_lints.rs12
-rw-r--r--tests/ui/outer_expn_info.rs2
-rw-r--r--tests/ui/outer_expn_info.stderr8
5 files changed, 42 insertions, 28 deletions
diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs
index de7a213d7a4..6d90d315f00 100644
--- a/clippy_lints/src/lib.rs
+++ b/clippy_lints/src/lib.rs
@@ -1,6 +1,7 @@
 // error-pattern:cargo-clippy
 
 #![feature(box_syntax)]
+#![feature(box_patterns)]
 #![feature(never_type)]
 #![feature(rustc_private)]
 #![feature(slice_patterns)]
@@ -668,7 +669,7 @@ pub fn register_plugins(reg: &mut rustc_plugin::Registry<'_>, conf: &Conf) {
         utils::internal_lints::CLIPPY_LINTS_INTERNAL,
         utils::internal_lints::COMPILER_LINT_FUNCTIONS,
         utils::internal_lints::LINT_WITHOUT_LINT_PASS,
-        utils::internal_lints::OUTER_EXPN_INFO,
+        utils::internal_lints::OUTER_EXPN_EXPN_INFO,
     ]);
 
     reg.register_lint_group("clippy::all", Some("clippy"), vec![
diff --git a/clippy_lints/src/redundant_clone.rs b/clippy_lints/src/redundant_clone.rs
index edcf41f758c..d24a20b079d 100644
--- a/clippy_lints/src/redundant_clone.rs
+++ b/clippy_lints/src/redundant_clone.rs
@@ -132,7 +132,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for RedundantClone {
                 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 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);
@@ -218,7 +218,7 @@ fn is_call_with_ref_arg<'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);
@@ -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);
                 }
@@ -271,28 +278,34 @@ fn find_stmt_assigns_to<'a, 'tcx: 'a>(
 fn base_local_and_movability<'tcx>(
     cx: &LateContext<'_, 'tcx>,
     mir: &mir::Body<'tcx>,
-    mut place: &mir::Place<'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
     }
 }
 
diff --git a/clippy_lints/src/utils/internal_lints.rs b/clippy_lints/src/utils/internal_lints.rs
index aba2543b13c..6393bf2add4 100644
--- a/clippy_lints/src/utils/internal_lints.rs
+++ b/clippy_lints/src/utils/internal_lints.rs
@@ -93,9 +93,9 @@ declare_clippy_lint! {
     /// ```rust
     /// expr.span.ctxt().outer_expn_info()
     /// ```
-    pub OUTER_EXPN_INFO,
+    pub OUTER_EXPN_EXPN_INFO,
     internal,
-    "using `cx.outer().expn_info()` instead of `cx.outer_expn_info()`"
+    "using `cx.outer_expn().expn_info()` instead of `cx.outer_expn_info()`"
 }
 
 declare_lint_pass!(ClippyLintsInternal => [CLIPPY_LINTS_INTERNAL]);
@@ -280,7 +280,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for CompilerLintFunctions {
 
 pub struct OuterExpnInfoPass;
 
-impl_lint_pass!(OuterExpnInfoPass => [OUTER_EXPN_INFO]);
+impl_lint_pass!(OuterExpnInfoPass => [OUTER_EXPN_EXPN_INFO]);
 
 impl<'a, 'tcx> LateLintPass<'a, 'tcx> for OuterExpnInfoPass {
     fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx hir::Expr) {
@@ -288,7 +288,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for OuterExpnInfoPass {
         let method_names: Vec<LocalInternedString> = method_names.iter().map(|s| s.as_str()).collect();
         let method_names: Vec<&str> = method_names.iter().map(std::convert::AsRef::as_ref).collect();
         if_chain! {
-            if let ["expn_info", "outer"] = method_names.as_slice();
+            if let ["expn_info", "outer_expn"] = method_names.as_slice();
             let args = arg_lists[1];
             if args.len() == 1;
             let self_arg = &args[0];
@@ -297,9 +297,9 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for OuterExpnInfoPass {
             then {
                 span_lint_and_sugg(
                     cx,
-                    OUTER_EXPN_INFO,
+                    OUTER_EXPN_EXPN_INFO,
                     expr.span.trim_start(self_arg.span).unwrap_or(expr.span),
-                    "usage of `outer().expn_info()`",
+                    "usage of `outer_expn().expn_info()`",
                     "try",
                     ".outer_expn_info()".to_string(),
                     Applicability::MachineApplicable,
diff --git a/tests/ui/outer_expn_info.rs b/tests/ui/outer_expn_info.rs
index 1bc6f688805..ed0542c9298 100644
--- a/tests/ui/outer_expn_info.rs
+++ b/tests/ui/outer_expn_info.rs
@@ -16,7 +16,7 @@ declare_lint_pass!(Pass => [TEST_LINT]);
 
 impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass {
     fn check_expr(&mut self, _cx: &LateContext<'a, 'tcx>, expr: &'tcx Expr) {
-        let _ = expr.span.ctxt().outer().expn_info();
+        let _ = expr.span.ctxt().outer_expn().expn_info();
     }
 }
 
diff --git a/tests/ui/outer_expn_info.stderr b/tests/ui/outer_expn_info.stderr
index d9efc91da8e..4bbd1493dc4 100644
--- a/tests/ui/outer_expn_info.stderr
+++ b/tests/ui/outer_expn_info.stderr
@@ -1,15 +1,15 @@
-error: usage of `outer().expn_info()`
+error: usage of `outer_expn().expn_info()`
   --> $DIR/outer_expn_info.rs:19:33
    |
-LL |         let _ = expr.span.ctxt().outer().expn_info();
-   |                                 ^^^^^^^^^^^^^^^^^^^^ help: try: `.outer_expn_info()`
+LL |         let _ = expr.span.ctxt().outer_expn().expn_info();
+   |                                 ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `.outer_expn_info()`
    |
 note: lint level defined here
   --> $DIR/outer_expn_info.rs:1:9
    |
 LL | #![deny(clippy::internal)]
    |         ^^^^^^^^^^^^^^^^
-   = note: `#[deny(clippy::outer_expn_info)]` implied by `#[deny(clippy::internal)]`
+   = note: `#[deny(clippy::outer_expn_expn_info)]` implied by `#[deny(clippy::internal)]`
 
 error: aborting due to previous error