about summary refs log tree commit diff
path: root/tests/ui/pattern
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2024-03-15 21:51:56 +0100
committerGitHub <noreply@github.com>2024-03-15 21:51:56 +0100
commit9e153ccd45d231146f79e476c9b2d5e6c45e728c (patch)
treec2f6e521b8b5fa54de7eb5b8fb1aa1693f762365 /tests/ui/pattern
parent72d78970ec7cb5cdf210290835d9f71d4d6663e2 (diff)
parent0953608debfa9d3df955f976e7bc857584ba1ed0 (diff)
downloadrust-9e153ccd45d231146f79e476c9b2d5e6c45e728c.tar.gz
rust-9e153ccd45d231146f79e476c9b2d5e6c45e728c.zip
Rollup merge of #122254 - estebank:issue-48677, r=oli-obk
Detect calls to .clone() on T: !Clone types on borrowck errors

When encountering a lifetime error on a type that *holds* a type that doesn't implement `Clone`, explore the item's body for potential calls to `.clone()` that are only cloning the reference `&T` instead of `T` because `T: !Clone`. If we find this, suggest `T: Clone`.

```
error[E0502]: cannot borrow `*list` as mutable because it is also borrowed as immutable
  --> $DIR/clone-on-ref.rs:7:5
   |
LL |     for v in list.iter() {
   |              ---- immutable borrow occurs here
LL |         cloned_items.push(v.clone())
   |                             ------- this call doesn't do anything, the result is still `&T` because `T` doesn't implement `Clone`
LL |     }
LL |     list.push(T::default());
   |     ^^^^^^^^^^^^^^^^^^^^^^^ mutable borrow occurs here
LL |
LL |     drop(cloned_items);
   |          ------------ immutable borrow later used here
   |
help: consider further restricting this bound
   |
LL | fn foo<T: Default + Clone>(list: &mut Vec<T>) {
   |                   +++++++
```
```
error[E0505]: cannot move out of `x` because it is borrowed
  --> $DIR/clone-on-ref.rs:23:10
   |
LL | fn qux(x: A) {
   |        - binding `x` declared here
LL |     let a = &x;
   |             -- borrow of `x` occurs here
LL |     let b = a.clone();
   |               ------- this call doesn't do anything, the result is still `&A` because `A` doesn't implement `Clone`
LL |     drop(x);
   |          ^ move out of `x` occurs here
LL |
LL |     println!("{b:?}");
   |               ----- borrow later used here
   |
help: consider annotating `A` with `#[derive(Clone)]`
   |
LL + #[derive(Clone)]
LL | struct A;
   |
```

Fix #48677.
Diffstat (limited to 'tests/ui/pattern')
-rw-r--r--tests/ui/pattern/bindings-after-at/bind-by-move-neither-can-live-while-the-other-survives-1.stderr4
-rw-r--r--tests/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse-promotion.stderr2
-rw-r--r--tests/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse.stderr50
-rw-r--r--tests/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.stderr8
-rw-r--r--tests/ui/pattern/bindings-after-at/default-binding-modes-both-sides-independent.stderr2
5 files changed, 33 insertions, 33 deletions
diff --git a/tests/ui/pattern/bindings-after-at/bind-by-move-neither-can-live-while-the-other-survives-1.stderr b/tests/ui/pattern/bindings-after-at/bind-by-move-neither-can-live-while-the-other-survives-1.stderr
index 25838fbf0ab..16a93a0d47d 100644
--- a/tests/ui/pattern/bindings-after-at/bind-by-move-neither-can-live-while-the-other-survives-1.stderr
+++ b/tests/ui/pattern/bindings-after-at/bind-by-move-neither-can-live-while-the-other-survives-1.stderr
@@ -13,7 +13,7 @@ LL |         Some(_z @ ref _y) => {}
    |              ^^   ------ value borrowed here after move
    |              |
    |              value moved into `_z` here
-   |              move occurs because `_z` has type `X` which does not implement the `Copy` trait
+   |              move occurs because `_z` has type `X`, which does not implement the `Copy` trait
    |
 help: borrow this binding in the pattern to avoid moving the value
    |
@@ -35,7 +35,7 @@ LL |         Some(_z @ ref mut _y) => {}
    |              ^^   ---------- value borrowed here after move
    |              |
    |              value moved into `_z` here
-   |              move occurs because `_z` has type `X` which does not implement the `Copy` trait
+   |              move occurs because `_z` has type `X`, which does not implement the `Copy` trait
    |
 help: borrow this binding in the pattern to avoid moving the value
    |
diff --git a/tests/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse-promotion.stderr b/tests/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse-promotion.stderr
index 815a4ade995..ea04d4bc055 100644
--- a/tests/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse-promotion.stderr
+++ b/tests/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse-promotion.stderr
@@ -5,7 +5,7 @@ LL |     let a @ ref b = U;
    |         ^   ----- value borrowed here after move
    |         |
    |         value moved into `a` here
-   |         move occurs because `a` has type `U` which does not implement the `Copy` trait
+   |         move occurs because `a` has type `U`, which does not implement the `Copy` trait
    |
 help: borrow this binding in the pattern to avoid moving the value
    |
diff --git a/tests/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse.stderr b/tests/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse.stderr
index fd7a51388bc..25c940a3200 100644
--- a/tests/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse.stderr
+++ b/tests/ui/pattern/bindings-after-at/borrowck-pat-by-move-and-ref-inverse.stderr
@@ -5,7 +5,7 @@ LL |     let a @ ref b = U;
    |         ^   ----- value borrowed here after move
    |         |
    |         value moved into `a` here
-   |         move occurs because `a` has type `U` which does not implement the `Copy` trait
+   |         move occurs because `a` has type `U`, which does not implement the `Copy` trait
    |
 help: borrow this binding in the pattern to avoid moving the value
    |
@@ -20,7 +20,7 @@ LL |     let a @ (mut b @ ref mut c, d @ ref e) = (U, U);
    |         |            |
    |         |            value borrowed here after move
    |         value moved into `a` here
-   |         move occurs because `a` has type `(U, U)` which does not implement the `Copy` trait
+   |         move occurs because `a` has type `(U, U)`, which does not implement the `Copy` trait
    |
 help: borrow this binding in the pattern to avoid moving the value
    |
@@ -34,7 +34,7 @@ LL |     let a @ (mut b @ ref mut c, d @ ref e) = (U, U);
    |              ^^^^^   --------- value borrowed here after move
    |              |
    |              value moved into `b` here
-   |              move occurs because `b` has type `U` which does not implement the `Copy` trait
+   |              move occurs because `b` has type `U`, which does not implement the `Copy` trait
    |
 help: borrow this binding in the pattern to avoid moving the value
    |
@@ -48,7 +48,7 @@ LL |     let a @ (mut b @ ref mut c, d @ ref e) = (U, U);
    |                                 ^   ----- value borrowed here after move
    |                                 |
    |                                 value moved into `d` here
-   |                                 move occurs because `d` has type `U` which does not implement the `Copy` trait
+   |                                 move occurs because `d` has type `U`, which does not implement the `Copy` trait
    |
 help: borrow this binding in the pattern to avoid moving the value
    |
@@ -63,7 +63,7 @@ LL |     let a @ [ref mut b, ref c] = [U, U];
    |         |    |
    |         |    value borrowed here after move
    |         value moved into `a` here
-   |         move occurs because `a` has type `[U; 2]` which does not implement the `Copy` trait
+   |         move occurs because `a` has type `[U; 2]`, which does not implement the `Copy` trait
    |
 help: borrow this binding in the pattern to avoid moving the value
    |
@@ -77,7 +77,7 @@ LL |     let a @ ref b = u();
    |         ^   ----- value borrowed here after move
    |         |
    |         value moved into `a` here
-   |         move occurs because `a` has type `U` which does not implement the `Copy` trait
+   |         move occurs because `a` has type `U`, which does not implement the `Copy` trait
    |
 help: borrow this binding in the pattern to avoid moving the value
    |
@@ -92,7 +92,7 @@ LL |     let a @ (mut b @ ref mut c, d @ ref e) = (u(), u());
    |         |            |
    |         |            value borrowed here after move
    |         value moved into `a` here
-   |         move occurs because `a` has type `(U, U)` which does not implement the `Copy` trait
+   |         move occurs because `a` has type `(U, U)`, which does not implement the `Copy` trait
    |
 help: borrow this binding in the pattern to avoid moving the value
    |
@@ -106,7 +106,7 @@ LL |     let a @ (mut b @ ref mut c, d @ ref e) = (u(), u());
    |              ^^^^^   --------- value borrowed here after move
    |              |
    |              value moved into `b` here
-   |              move occurs because `b` has type `U` which does not implement the `Copy` trait
+   |              move occurs because `b` has type `U`, which does not implement the `Copy` trait
    |
 help: borrow this binding in the pattern to avoid moving the value
    |
@@ -120,7 +120,7 @@ LL |     let a @ (mut b @ ref mut c, d @ ref e) = (u(), u());
    |                                 ^   ----- value borrowed here after move
    |                                 |
    |                                 value moved into `d` here
-   |                                 move occurs because `d` has type `U` which does not implement the `Copy` trait
+   |                                 move occurs because `d` has type `U`, which does not implement the `Copy` trait
    |
 help: borrow this binding in the pattern to avoid moving the value
    |
@@ -135,7 +135,7 @@ LL |     let a @ [ref mut b, ref c] = [u(), u()];
    |         |    |
    |         |    value borrowed here after move
    |         value moved into `a` here
-   |         move occurs because `a` has type `[U; 2]` which does not implement the `Copy` trait
+   |         move occurs because `a` has type `[U; 2]`, which does not implement the `Copy` trait
    |
 help: borrow this binding in the pattern to avoid moving the value
    |
@@ -149,7 +149,7 @@ LL |         a @ Some(ref b) => {}
    |         ^        ----- value borrowed here after move
    |         |
    |         value moved into `a` here
-   |         move occurs because `a` has type `Option<U>` which does not implement the `Copy` trait
+   |         move occurs because `a` has type `Option<U>`, which does not implement the `Copy` trait
    |
 help: borrow this binding in the pattern to avoid moving the value
    |
@@ -164,7 +164,7 @@ LL |         a @ Some((mut b @ ref mut c, d @ ref e)) => {}
    |         |                 |
    |         |                 value borrowed here after move
    |         value moved into `a` here
-   |         move occurs because `a` has type `Option<(U, U)>` which does not implement the `Copy` trait
+   |         move occurs because `a` has type `Option<(U, U)>`, which does not implement the `Copy` trait
    |
 help: borrow this binding in the pattern to avoid moving the value
    |
@@ -178,7 +178,7 @@ LL |         a @ Some((mut b @ ref mut c, d @ ref e)) => {}
    |                   ^^^^^   --------- value borrowed here after move
    |                   |
    |                   value moved into `b` here
-   |                   move occurs because `b` has type `U` which does not implement the `Copy` trait
+   |                   move occurs because `b` has type `U`, which does not implement the `Copy` trait
    |
 help: borrow this binding in the pattern to avoid moving the value
    |
@@ -192,7 +192,7 @@ LL |         a @ Some((mut b @ ref mut c, d @ ref e)) => {}
    |                                      ^   ----- value borrowed here after move
    |                                      |
    |                                      value moved into `d` here
-   |                                      move occurs because `d` has type `U` which does not implement the `Copy` trait
+   |                                      move occurs because `d` has type `U`, which does not implement the `Copy` trait
    |
 help: borrow this binding in the pattern to avoid moving the value
    |
@@ -207,7 +207,7 @@ LL |         mut a @ Some([ref b, ref mut c]) => {}
    |         |             |
    |         |             value borrowed here after move
    |         value moved into `a` here
-   |         move occurs because `a` has type `Option<[U; 2]>` which does not implement the `Copy` trait
+   |         move occurs because `a` has type `Option<[U; 2]>`, which does not implement the `Copy` trait
    |
 help: borrow this binding in the pattern to avoid moving the value
    |
@@ -221,7 +221,7 @@ LL |         a @ Some(ref b) => {}
    |         ^        ----- value borrowed here after move
    |         |
    |         value moved into `a` here
-   |         move occurs because `a` has type `Option<U>` which does not implement the `Copy` trait
+   |         move occurs because `a` has type `Option<U>`, which does not implement the `Copy` trait
    |
 help: borrow this binding in the pattern to avoid moving the value
    |
@@ -236,7 +236,7 @@ LL |         a @ Some((mut b @ ref mut c, d @ ref e)) => {}
    |         |                 |
    |         |                 value borrowed here after move
    |         value moved into `a` here
-   |         move occurs because `a` has type `Option<(U, U)>` which does not implement the `Copy` trait
+   |         move occurs because `a` has type `Option<(U, U)>`, which does not implement the `Copy` trait
    |
 help: borrow this binding in the pattern to avoid moving the value
    |
@@ -250,7 +250,7 @@ LL |         a @ Some((mut b @ ref mut c, d @ ref e)) => {}
    |                   ^^^^^   --------- value borrowed here after move
    |                   |
    |                   value moved into `b` here
-   |                   move occurs because `b` has type `U` which does not implement the `Copy` trait
+   |                   move occurs because `b` has type `U`, which does not implement the `Copy` trait
    |
 help: borrow this binding in the pattern to avoid moving the value
    |
@@ -264,7 +264,7 @@ LL |         a @ Some((mut b @ ref mut c, d @ ref e)) => {}
    |                                      ^   ----- value borrowed here after move
    |                                      |
    |                                      value moved into `d` here
-   |                                      move occurs because `d` has type `U` which does not implement the `Copy` trait
+   |                                      move occurs because `d` has type `U`, which does not implement the `Copy` trait
    |
 help: borrow this binding in the pattern to avoid moving the value
    |
@@ -279,7 +279,7 @@ LL |         mut a @ Some([ref b, ref mut c]) => {}
    |         |             |
    |         |             value borrowed here after move
    |         value moved into `a` here
-   |         move occurs because `a` has type `Option<[U; 2]>` which does not implement the `Copy` trait
+   |         move occurs because `a` has type `Option<[U; 2]>`, which does not implement the `Copy` trait
    |
 help: borrow this binding in the pattern to avoid moving the value
    |
@@ -349,7 +349,7 @@ LL |     fn f1(a @ ref b: U) {}
    |           ^   ----- value borrowed here after move
    |           |
    |           value moved into `a` here
-   |           move occurs because `a` has type `U` which does not implement the `Copy` trait
+   |           move occurs because `a` has type `U`, which does not implement the `Copy` trait
    |
 help: borrow this binding in the pattern to avoid moving the value
    |
@@ -364,7 +364,7 @@ LL |     fn f2(mut a @ (b @ ref c, mut d @ ref e): (U, U)) {}
    |           |            |
    |           |            value borrowed here after move
    |           value moved into `a` here
-   |           move occurs because `a` has type `(U, U)` which does not implement the `Copy` trait
+   |           move occurs because `a` has type `(U, U)`, which does not implement the `Copy` trait
    |
 help: borrow this binding in the pattern to avoid moving the value
    |
@@ -378,7 +378,7 @@ LL |     fn f2(mut a @ (b @ ref c, mut d @ ref e): (U, U)) {}
    |                    ^   ----- value borrowed here after move
    |                    |
    |                    value moved into `b` here
-   |                    move occurs because `b` has type `U` which does not implement the `Copy` trait
+   |                    move occurs because `b` has type `U`, which does not implement the `Copy` trait
    |
 help: borrow this binding in the pattern to avoid moving the value
    |
@@ -392,7 +392,7 @@ LL |     fn f2(mut a @ (b @ ref c, mut d @ ref e): (U, U)) {}
    |                               ^^^^^   ----- value borrowed here after move
    |                               |
    |                               value moved into `d` here
-   |                               move occurs because `d` has type `U` which does not implement the `Copy` trait
+   |                               move occurs because `d` has type `U`, which does not implement the `Copy` trait
    |
 help: borrow this binding in the pattern to avoid moving the value
    |
@@ -417,7 +417,7 @@ LL |     fn f3(a @ [ref mut b, ref c]: [U; 2]) {}
    |           |    |
    |           |    value borrowed here after move
    |           value moved into `a` here
-   |           move occurs because `a` has type `[U; 2]` which does not implement the `Copy` trait
+   |           move occurs because `a` has type `[U; 2]`, which does not implement the `Copy` trait
    |
 help: borrow this binding in the pattern to avoid moving the value
    |
diff --git a/tests/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.stderr b/tests/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.stderr
index 3446148d2b1..76085f897ff 100644
--- a/tests/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.stderr
+++ b/tests/ui/pattern/bindings-after-at/borrowck-pat-ref-mut-twice.stderr
@@ -78,7 +78,7 @@ LL |     let a @ (ref mut b, ref mut c) = (U, U);
    |         |    |
    |         |    value borrowed here after move
    |         value moved into `a` here
-   |         move occurs because `a` has type `(U, U)` which does not implement the `Copy` trait
+   |         move occurs because `a` has type `(U, U)`, which does not implement the `Copy` trait
    |
 help: borrow this binding in the pattern to avoid moving the value
    |
@@ -94,7 +94,7 @@ LL |     let a @ (b, [c, d]) = &mut val; // Same as ^--
    |         |    |   value borrowed here after move
    |         |    value borrowed here after move
    |         value moved into `a` here
-   |         move occurs because `a` has type `&mut (U, [U; 2])` which does not implement the `Copy` trait
+   |         move occurs because `a` has type `&mut (U, [U; 2])`, which does not implement the `Copy` trait
    |
 help: borrow this binding in the pattern to avoid moving the value
    |
@@ -108,7 +108,7 @@ LL |     let a @ &mut ref mut b = &mut U;
    |         ^        --------- value borrowed here after move
    |         |
    |         value moved into `a` here
-   |         move occurs because `a` has type `&mut U` which does not implement the `Copy` trait
+   |         move occurs because `a` has type `&mut U`, which does not implement the `Copy` trait
    |
 help: borrow this binding in the pattern to avoid moving the value
    |
@@ -123,7 +123,7 @@ LL |     let a @ &mut (ref mut b, ref mut c) = &mut (U, U);
    |         |         |
    |         |         value borrowed here after move
    |         value moved into `a` here
-   |         move occurs because `a` has type `&mut (U, U)` which does not implement the `Copy` trait
+   |         move occurs because `a` has type `&mut (U, U)`, which does not implement the `Copy` trait
    |
 help: borrow this binding in the pattern to avoid moving the value
    |
diff --git a/tests/ui/pattern/bindings-after-at/default-binding-modes-both-sides-independent.stderr b/tests/ui/pattern/bindings-after-at/default-binding-modes-both-sides-independent.stderr
index 36515c1a29b..a0a43e83a6a 100644
--- a/tests/ui/pattern/bindings-after-at/default-binding-modes-both-sides-independent.stderr
+++ b/tests/ui/pattern/bindings-after-at/default-binding-modes-both-sides-independent.stderr
@@ -29,7 +29,7 @@ LL |         Ok(ref a @ b) | Err(b @ ref a) => {
    |                             ^   ----- value borrowed here after move
    |                             |
    |                             value moved into `b` here
-   |                             move occurs because `b` has type `NotCopy` which does not implement the `Copy` trait
+   |                             move occurs because `b` has type `NotCopy`, which does not implement the `Copy` trait
    |
 help: borrow this binding in the pattern to avoid moving the value
    |