]> git.lizzy.rs Git - rust.git/blobdiff - clippy_lints/src/swap.rs
Auto merge of #4551 - mikerite:fix-ice-reporting, r=llogiq
[rust.git] / clippy_lints / src / swap.rs
index 11ab5b8762821f11eb57ca54f2e55093238664e0..cde49db2375b6ef8d574864ef11dbd51362b1e80 100644 (file)
@@ -1,6 +1,7 @@
 use crate::utils::sugg::Sugg;
 use crate::utils::{
-    differing_macro_contexts, match_type, paths, snippet, span_lint_and_then, walk_ptrs_ty, SpanlessEq,
+    differing_macro_contexts, is_type_diagnostic_item, match_type, paths, snippet, span_lint_and_then, walk_ptrs_ty,
+    SpanlessEq,
 };
 use if_chain::if_chain;
 use matches::matches;
@@ -9,6 +10,7 @@
 use rustc::ty;
 use rustc::{declare_lint_pass, declare_tool_lint};
 use rustc_errors::Applicability;
+use syntax_pos::Symbol;
 
 declare_clippy_lint! {
     /// **What it does:** Checks for manual swapping.
     /// a = b;
     /// b = a;
     /// ```
+    /// Could be written as:
+    /// ```rust
+    /// # let mut a = 1;
+    /// # let mut b = 2;
+    /// std::mem::swap(&mut a, &mut b);
+    /// ```
     pub ALMOST_SWAPPED,
     correctness,
     "`foo = bar; bar = foo` sequence"
@@ -101,7 +109,7 @@ fn check_for_slice<'a>(
 
                                 if matches!(ty.sty, ty::Slice(_)) ||
                                     matches!(ty.sty, ty::Array(_, _)) ||
-                                    match_type(cx, ty, &paths::VEC) ||
+                                    is_type_diagnostic_item(cx, ty, Symbol::intern("vec_type")) ||
                                     match_type(cx, ty, &paths::VEC_DEQUE) {
                                         return Some((lhs1, idx1, idx2));
                                 }
@@ -112,6 +120,14 @@ fn check_for_slice<'a>(
                     None
                 }
 
+                if let ExprKind::Field(ref lhs1, _) = lhs1.node {
+                    if let ExprKind::Field(ref lhs2, _) = lhs2.node {
+                        if lhs1.hir_id.owner_def_id() == lhs2.hir_id.owner_def_id() {
+                            return;
+                        }
+                    }
+                }
+
                 let (replace, what, sugg) = if let Some((slice, idx1, idx2)) = check_for_slice(cx, lhs1, lhs2) {
                     if let Some(slice) = Sugg::hir_opt(cx, slice) {
                         (false,