From 8a4ffb881d989be8e5bbbfa45cd5aa971a6179f2 Mon Sep 17 00:00:00 2001
From: valentine-mario <valentine13400@gmail.com>
Date: Thu, 5 Aug 2021 16:15:44 +0100
Subject: [PATCH] fixed bug that had to deal with mut and non mut suggestion

---
 clippy_lints/src/methods/extend_with_drain.rs | 8 ++++++--
 tests/ui/extend_with_drain.fixed              | 7 ++++++-
 tests/ui/extend_with_drain.rs                 | 7 ++++++-
 tests/ui/extend_with_drain.stderr             | 8 +++++++-
 4 files changed, 25 insertions(+), 5 deletions(-)

diff --git a/clippy_lints/src/methods/extend_with_drain.rs b/clippy_lints/src/methods/extend_with_drain.rs
index 57e10ce42f8..8829b8c5f4d 100644
--- a/clippy_lints/src/methods/extend_with_drain.rs
+++ b/clippy_lints/src/methods/extend_with_drain.rs
@@ -16,7 +16,10 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, recv: &Expr<'_>, arg:
         //check source object
         if let ExprKind::MethodCall(src_method, _, [drain_vec, drain_arg], _) = &arg.kind;
         if src_method.ident.as_str() == "drain";
-        if let src_ty = cx.typeck_results().expr_ty(drain_vec).peel_refs();
+        let src_ty = cx.typeck_results().expr_ty(drain_vec);
+        //check if actual src type is mutable for code suggestion
+        let immutable = src_ty.is_mutable_ptr();
+        let src_ty = src_ty.peel_refs();
         if is_type_diagnostic_item(cx, src_ty, sym::vec_type);
         //check drain range
         if let src_ty_range = cx.typeck_results().expr_ty(drain_arg).peel_refs();
@@ -30,8 +33,9 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, recv: &Expr<'_>, arg:
                 "use of `extend` instead of `append` for adding the full range of a second vector",
                 "try this",
                 format!(
-                    "{}.append(&mut {})",
+                    "{}.append({}{})",
                     snippet_with_applicability(cx, recv.span, "..", &mut applicability),
+                    if immutable { "" } else { "&mut " },
                     snippet_with_applicability(cx, drain_vec.span, "..", &mut applicability)
                 ),
                 applicability,
diff --git a/tests/ui/extend_with_drain.fixed b/tests/ui/extend_with_drain.fixed
index 00170e649e2..e863870e7d6 100644
--- a/tests/ui/extend_with_drain.fixed
+++ b/tests/ui/extend_with_drain.fixed
@@ -41,7 +41,12 @@ fn main() {
 
     let mut heap = BinaryHeap::from(vec![1, 3]);
     let mut heap2 = BinaryHeap::from(vec![]);
-    heap2.extend(heap.drain())
+    heap2.extend(heap.drain());
+
+    let mut x = vec![0, 1, 2, 3, 5];
+    let ref_x = &mut x;
+    let mut y = Vec::new();
+    y.append(ref_x);
 }
 
 fn return_vector() -> Vec<u8> {
diff --git a/tests/ui/extend_with_drain.rs b/tests/ui/extend_with_drain.rs
index d76458c3289..dcb36b5951c 100644
--- a/tests/ui/extend_with_drain.rs
+++ b/tests/ui/extend_with_drain.rs
@@ -41,7 +41,12 @@ fn main() {
 
     let mut heap = BinaryHeap::from(vec![1, 3]);
     let mut heap2 = BinaryHeap::from(vec![]);
-    heap2.extend(heap.drain())
+    heap2.extend(heap.drain());
+
+    let mut x = vec![0, 1, 2, 3, 5];
+    let ref_x = &mut x;
+    let mut y = Vec::new();
+    y.extend(ref_x.drain(..));
 }
 
 fn return_vector() -> Vec<u8> {
diff --git a/tests/ui/extend_with_drain.stderr b/tests/ui/extend_with_drain.stderr
index 57f344716a1..da14ddb25b3 100644
--- a/tests/ui/extend_with_drain.stderr
+++ b/tests/ui/extend_with_drain.stderr
@@ -18,5 +18,11 @@ error: use of `extend` instead of `append` for adding the full range of a second
 LL |     vec11.extend(return_vector().drain(..));
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `vec11.append(&mut return_vector())`
 
-error: aborting due to 3 previous errors
+error: use of `extend` instead of `append` for adding the full range of a second vector
+  --> $DIR/extend_with_drain.rs:49:5
+   |
+LL |     y.extend(ref_x.drain(..));
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `y.append(ref_x)`
+
+error: aborting due to 4 previous errors