about summary refs log tree commit diff
path: root/tests/ui
diff options
context:
space:
mode:
authorEsteban Küber <esteban@kuber.com.ar>2025-07-20 02:15:45 +0000
committerEsteban Küber <esteban@kuber.com.ar>2025-07-21 16:21:23 +0000
commit5082e6a300974459aec6dc73e76cc039c3a517c1 (patch)
treec994ff732c6327c890a149009fddc40f041dccce /tests/ui
parent690ae523e5c0ac9602db7bbe2b8094ee422e4d0f (diff)
downloadrust-5082e6a300974459aec6dc73e76cc039c3a517c1.tar.gz
rust-5082e6a300974459aec6dc73e76cc039c3a517c1.zip
Generalize logic pointing at binding moved into closure
Account not only for `fn` parameters when moving non-`Copy` values into closure, but also for let bindings.

```
error[E0507]: cannot move out of `bar`, a captured variable in an `FnMut` closure
  --> $DIR/borrowck-move-by-capture.rs:9:29
   |
LL |     let bar: Box<_> = Box::new(3);
   |         ---  ------ move occurs because `bar` has type `Box<isize>`, which does not implement the `Copy` trait
   |         |
   |         captured outer variable
LL |     let _g = to_fn_mut(|| {
   |                        -- captured by this `FnMut` closure
LL |         let _h = to_fn_once(move || -> isize { *bar });
   |                             ^^^^^^^^^^^^^^^^   ---- variable moved due to use in closure
   |                             |
   |                             `bar` is moved here
   |
help: consider cloning the value before moving it into the closure
   |
LL ~         let value = bar.clone();
LL ~         let _h = to_fn_once(move || -> isize { value });
   |
```

```
error[E0507]: cannot move out of `y`, a captured variable in an `Fn` closure
  --> $DIR/unboxed-closures-move-upvar-from-non-once-ref-closure.rs:12:9
   |
LL |     let y = vec![format!("World")];
   |         -   ---------------------- move occurs because `y` has type `Vec<String>`, which does not implement the `Copy` trait
   |         |
   |         captured outer variable
LL |     call(|| {
   |          -- captured by this `Fn` closure
LL |         y.into_iter();
   |         ^ ----------- `y` moved due to this method call
   |         |
   |         `y` is moved here
   |
note: `into_iter` takes ownership of the receiver `self`, which moves `y`
  --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
help: you can `clone` the value and consume it, but this might not be your desired behavior
   |
LL |         <Vec<String> as Clone>::clone(&y).into_iter();
   |         +++++++++++++++++++++++++++++++ +
help: consider cloning the value if the performance cost is acceptable
   |
LL |         y.clone().into_iter();
   |          ++++++++
```
Diffstat (limited to 'tests/ui')
-rw-r--r--tests/ui/borrowck/borrowck-in-static.stderr6
-rw-r--r--tests/ui/borrowck/borrowck-move-by-capture.stderr10
-rw-r--r--tests/ui/borrowck/issue-103624.stderr7
-rw-r--r--tests/ui/borrowck/unboxed-closures-move-upvar-from-non-once-ref-closure.stderr6
-rw-r--r--tests/ui/issues/issue-4335.stderr2
-rw-r--r--tests/ui/moves/moves-based-on-type-move-out-of-closure-env-issue-1965.stderr6
-rw-r--r--tests/ui/nll/issue-52663-span-decl-captured-variable.stderr6
-rw-r--r--tests/ui/span/borrowck-call-is-borrow-issue-12224.stderr18
-rw-r--r--tests/ui/suggestions/option-content-move2.stderr18
-rw-r--r--tests/ui/suggestions/option-content-move3.stderr18
-rw-r--r--tests/ui/unboxed-closures/unboxed-closure-illegal-move.stderr24
11 files changed, 70 insertions, 51 deletions
diff --git a/tests/ui/borrowck/borrowck-in-static.stderr b/tests/ui/borrowck/borrowck-in-static.stderr
index 745b02ae21b..9bcf64dd62e 100644
--- a/tests/ui/borrowck/borrowck-in-static.stderr
+++ b/tests/ui/borrowck/borrowck-in-static.stderr
@@ -2,9 +2,11 @@ error[E0507]: cannot move out of `x`, a captured variable in an `Fn` closure
   --> $DIR/borrowck-in-static.rs:5:17
    |
 LL |     let x = Box::new(0);
-   |         - captured outer variable
+   |         -   ----------- move occurs because `x` has type `Box<i32>`, which does not implement the `Copy` trait
+   |         |
+   |         captured outer variable
 LL |     Box::new(|| x)
-   |              -- ^ move occurs because `x` has type `Box<i32>`, which does not implement the `Copy` trait
+   |              -- ^ `x` is moved here
    |              |
    |              captured by this `Fn` closure
    |
diff --git a/tests/ui/borrowck/borrowck-move-by-capture.stderr b/tests/ui/borrowck/borrowck-move-by-capture.stderr
index 58d5e90e990..732af1593d6 100644
--- a/tests/ui/borrowck/borrowck-move-by-capture.stderr
+++ b/tests/ui/borrowck/borrowck-move-by-capture.stderr
@@ -2,14 +2,14 @@ error[E0507]: cannot move out of `bar`, a captured variable in an `FnMut` closur
   --> $DIR/borrowck-move-by-capture.rs:9:29
    |
 LL |     let bar: Box<_> = Box::new(3);
-   |         --- captured outer variable
+   |         ---  ------ move occurs because `bar` has type `Box<isize>`, which does not implement the `Copy` trait
+   |         |
+   |         captured outer variable
 LL |     let _g = to_fn_mut(|| {
    |                        -- captured by this `FnMut` closure
 LL |         let _h = to_fn_once(move || -> isize { *bar });
-   |                             ^^^^^^^^^^^^^^^^   ----
-   |                             |                  |
-   |                             |                  variable moved due to use in closure
-   |                             |                  move occurs because `bar` has type `Box<isize>`, which does not implement the `Copy` trait
+   |                             ^^^^^^^^^^^^^^^^   ---- variable moved due to use in closure
+   |                             |
    |                             `bar` is moved here
    |
 help: consider cloning the value before moving it into the closure
diff --git a/tests/ui/borrowck/issue-103624.stderr b/tests/ui/borrowck/issue-103624.stderr
index 603055beadc..af65deb16dc 100644
--- a/tests/ui/borrowck/issue-103624.stderr
+++ b/tests/ui/borrowck/issue-103624.stderr
@@ -2,13 +2,16 @@ error[E0507]: cannot move out of `self.b`, as `self` is a captured variable in a
   --> $DIR/issue-103624.rs:16:13
    |
 LL |     async fn foo(&self) {
-   |                  ----- captured outer variable
+   |                  -----
+   |                  |
+   |                  captured outer variable
+   |                  move occurs because `self.b` has type `StructB`, which does not implement the `Copy` trait
 LL |         let bar = self.b.bar().await;
 LL |         spawn_blocking(move || {
    |                        ------- captured by this `Fn` closure
 LL |
 LL |             self.b;
-   |             ^^^^^^ move occurs because `self.b` has type `StructB`, which does not implement the `Copy` trait
+   |             ^^^^^^ `self.b` is moved here
    |
 note: if `StructB` implemented `Clone`, you could clone the value
   --> $DIR/issue-103624.rs:23:1
diff --git a/tests/ui/borrowck/unboxed-closures-move-upvar-from-non-once-ref-closure.stderr b/tests/ui/borrowck/unboxed-closures-move-upvar-from-non-once-ref-closure.stderr
index 177e9c8d248..da0e133ba02 100644
--- a/tests/ui/borrowck/unboxed-closures-move-upvar-from-non-once-ref-closure.stderr
+++ b/tests/ui/borrowck/unboxed-closures-move-upvar-from-non-once-ref-closure.stderr
@@ -2,13 +2,15 @@ error[E0507]: cannot move out of `y`, a captured variable in an `Fn` closure
   --> $DIR/unboxed-closures-move-upvar-from-non-once-ref-closure.rs:12:9
    |
 LL |     let y = vec![format!("World")];
-   |         - captured outer variable
+   |         -   ---------------------- move occurs because `y` has type `Vec<String>`, which does not implement the `Copy` trait
+   |         |
+   |         captured outer variable
 LL |     call(|| {
    |          -- captured by this `Fn` closure
 LL |         y.into_iter();
    |         ^ ----------- `y` moved due to this method call
    |         |
-   |         move occurs because `y` has type `Vec<String>`, which does not implement the `Copy` trait
+   |         `y` is moved here
    |
 note: `into_iter` takes ownership of the receiver `self`, which moves `y`
   --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
diff --git a/tests/ui/issues/issue-4335.stderr b/tests/ui/issues/issue-4335.stderr
index 1f1a2595a31..42ac6322564 100644
--- a/tests/ui/issues/issue-4335.stderr
+++ b/tests/ui/issues/issue-4335.stderr
@@ -6,7 +6,7 @@ LL | fn f<'r, T>(v: &'r T) -> Box<dyn FnMut() -> T + 'r> {
    |             |
    |             captured outer variable
 LL |     id(Box::new(|| *v))
-   |                 -- ^^
+   |                 -- ^^ `*v` is moved here
    |                 |
    |                 captured by this `FnMut` closure
    |
diff --git a/tests/ui/moves/moves-based-on-type-move-out-of-closure-env-issue-1965.stderr b/tests/ui/moves/moves-based-on-type-move-out-of-closure-env-issue-1965.stderr
index 523134a9425..51d0f85c031 100644
--- a/tests/ui/moves/moves-based-on-type-move-out-of-closure-env-issue-1965.stderr
+++ b/tests/ui/moves/moves-based-on-type-move-out-of-closure-env-issue-1965.stderr
@@ -2,9 +2,11 @@ error[E0507]: cannot move out of `i`, a captured variable in an `Fn` closure
   --> $DIR/moves-based-on-type-move-out-of-closure-env-issue-1965.rs:9:28
    |
 LL |     let i = Box::new(3);
-   |         - captured outer variable
+   |         -   ----------- move occurs because `i` has type `Box<usize>`, which does not implement the `Copy` trait
+   |         |
+   |         captured outer variable
 LL |     let _f = to_fn(|| test(i));
-   |                    --      ^ move occurs because `i` has type `Box<usize>`, which does not implement the `Copy` trait
+   |                    --      ^ `i` is moved here
    |                    |
    |                    captured by this `Fn` closure
    |
diff --git a/tests/ui/nll/issue-52663-span-decl-captured-variable.stderr b/tests/ui/nll/issue-52663-span-decl-captured-variable.stderr
index fbaec8a6008..57546037006 100644
--- a/tests/ui/nll/issue-52663-span-decl-captured-variable.stderr
+++ b/tests/ui/nll/issue-52663-span-decl-captured-variable.stderr
@@ -2,9 +2,11 @@ error[E0507]: cannot move out of `x.0`, as `x` is a captured variable in an `Fn`
   --> $DIR/issue-52663-span-decl-captured-variable.rs:8:26
    |
 LL |        let x = (vec![22], vec![44]);
-   |            - captured outer variable
+   |            -   -------------------- move occurs because `x.0` has type `Vec<i32>`, which does not implement the `Copy` trait
+   |            |
+   |            captured outer variable
 LL |        expect_fn(|| drop(x.0));
-   |                  --      ^^^ move occurs because `x.0` has type `Vec<i32>`, which does not implement the `Copy` trait
+   |                  --      ^^^ `x.0` is moved here
    |                  |
    |                  captured by this `Fn` closure
    |
diff --git a/tests/ui/span/borrowck-call-is-borrow-issue-12224.stderr b/tests/ui/span/borrowck-call-is-borrow-issue-12224.stderr
index f37dc320fa3..28761692413 100644
--- a/tests/ui/span/borrowck-call-is-borrow-issue-12224.stderr
+++ b/tests/ui/span/borrowck-call-is-borrow-issue-12224.stderr
@@ -35,14 +35,18 @@ LL | fn test4(f: &mut Test) {
 error[E0507]: cannot move out of `f`, a captured variable in an `FnMut` closure
   --> $DIR/borrowck-call-is-borrow-issue-12224.rs:57:13
    |
-LL |     let mut f = move |g: Box<dyn FnMut(isize)>, b: isize| {
-   |         ----- captured outer variable
-...
-LL |     f(Box::new(|a| {
-   |                --- captured by this `FnMut` closure
+LL |       let mut f = move |g: Box<dyn FnMut(isize)>, b: isize| {
+   |  _________-----___-
+   | |         |
+   | |         captured outer variable
+LL | |         let _ = s.len();
+LL | |     };
+   | |_____- move occurs because `f` has type `{closure@$DIR/borrowck-call-is-borrow-issue-12224.rs:52:17: 52:58}`, which does not implement the `Copy` trait
+LL |       f(Box::new(|a| {
+   |                  --- captured by this `FnMut` closure
 LL |
-LL |         foo(f);
-   |             ^ move occurs because `f` has type `{closure@$DIR/borrowck-call-is-borrow-issue-12224.rs:52:17: 52:58}`, which does not implement the `Copy` trait
+LL |           foo(f);
+   |               ^ `f` is moved here
    |
 help: consider cloning the value if the performance cost is acceptable
    |
diff --git a/tests/ui/suggestions/option-content-move2.stderr b/tests/ui/suggestions/option-content-move2.stderr
index be97cba17b9..436441d6f1b 100644
--- a/tests/ui/suggestions/option-content-move2.stderr
+++ b/tests/ui/suggestions/option-content-move2.stderr
@@ -2,7 +2,9 @@ error[E0507]: cannot move out of `var`, a captured variable in an `FnMut` closur
   --> $DIR/option-content-move2.rs:11:9
    |
 LL |     let mut var = None;
-   |         ------- captured outer variable
+   |         -------   ---- move occurs because `var` has type `Option<NotCopyable>`, which does not implement the `Copy` trait
+   |         |
+   |         captured outer variable
 LL |     func(|| {
    |          -- captured by this `FnMut` closure
 LL |         // Shouldn't suggest `move ||.as_ref()` here
@@ -10,16 +12,15 @@ LL |         move || {
    |         ^^^^^^^ `var` is moved here
 LL |
 LL |             var = Some(NotCopyable);
-   |             ---
-   |             |
-   |             variable moved due to use in closure
-   |             move occurs because `var` has type `Option<NotCopyable>`, which does not implement the `Copy` trait
+   |             --- variable moved due to use in closure
 
 error[E0507]: cannot move out of `var`, a captured variable in an `FnMut` closure
   --> $DIR/option-content-move2.rs:21:9
    |
 LL |     let mut var = None;
-   |         ------- captured outer variable
+   |         -------   ---- move occurs because `var` has type `Option<NotCopyableButCloneable>`, which does not implement the `Copy` trait
+   |         |
+   |         captured outer variable
 LL |     func(|| {
    |          -- captured by this `FnMut` closure
 LL |         // Shouldn't suggest `move ||.as_ref()` nor to `clone()` here
@@ -27,10 +28,7 @@ LL |         move || {
    |         ^^^^^^^ `var` is moved here
 LL |
 LL |             var = Some(NotCopyableButCloneable);
-   |             ---
-   |             |
-   |             variable moved due to use in closure
-   |             move occurs because `var` has type `Option<NotCopyableButCloneable>`, which does not implement the `Copy` trait
+   |             --- variable moved due to use in closure
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/suggestions/option-content-move3.stderr b/tests/ui/suggestions/option-content-move3.stderr
index faaf8a9df9d..68c52352a65 100644
--- a/tests/ui/suggestions/option-content-move3.stderr
+++ b/tests/ui/suggestions/option-content-move3.stderr
@@ -26,17 +26,16 @@ error[E0507]: cannot move out of `var`, a captured variable in an `FnMut` closur
   --> $DIR/option-content-move3.rs:12:9
    |
 LL |     let var = NotCopyable;
-   |         --- captured outer variable
+   |         ---   ----------- move occurs because `var` has type `NotCopyable`, which does not implement the `Copy` trait
+   |         |
+   |         captured outer variable
 LL |     func(|| {
    |          -- captured by this `FnMut` closure
 LL |         // Shouldn't suggest `move ||.as_ref()` here
 LL |         move || {
    |         ^^^^^^^ `var` is moved here
 LL |             let x = var;
-   |                     ---
-   |                     |
-   |                     variable moved due to use in closure
-   |                     move occurs because `var` has type `NotCopyable`, which does not implement the `Copy` trait
+   |                     --- variable moved due to use in closure
    |
 note: if `NotCopyable` implemented `Clone`, you could clone the value
   --> $DIR/option-content-move3.rs:2:1
@@ -67,17 +66,16 @@ error[E0507]: cannot move out of `var`, a captured variable in an `FnMut` closur
   --> $DIR/option-content-move3.rs:23:9
    |
 LL |     let var = NotCopyableButCloneable;
-   |         --- captured outer variable
+   |         ---   ----------------------- move occurs because `var` has type `NotCopyableButCloneable`, which does not implement the `Copy` trait
+   |         |
+   |         captured outer variable
 LL |     func(|| {
    |          -- captured by this `FnMut` closure
 LL |         // Shouldn't suggest `move ||.as_ref()` here
 LL |         move || {
    |         ^^^^^^^ `var` is moved here
 LL |             let x = var;
-   |                     ---
-   |                     |
-   |                     variable moved due to use in closure
-   |                     move occurs because `var` has type `NotCopyableButCloneable`, which does not implement the `Copy` trait
+   |                     --- variable moved due to use in closure
    |
 help: consider cloning the value before moving it into the closure
    |
diff --git a/tests/ui/unboxed-closures/unboxed-closure-illegal-move.stderr b/tests/ui/unboxed-closures/unboxed-closure-illegal-move.stderr
index cf4391311d0..8d9a61cb681 100644
--- a/tests/ui/unboxed-closures/unboxed-closure-illegal-move.stderr
+++ b/tests/ui/unboxed-closures/unboxed-closure-illegal-move.stderr
@@ -2,9 +2,11 @@ error[E0507]: cannot move out of `x`, a captured variable in an `Fn` closure
   --> $DIR/unboxed-closure-illegal-move.rs:15:31
    |
 LL |         let x = Box::new(0);
-   |             - captured outer variable
+   |             -   ----------- move occurs because `x` has type `Box<i32>`, which does not implement the `Copy` trait
+   |             |
+   |             captured outer variable
 LL |         let f = to_fn(|| drop(x));
-   |                       --      ^ move occurs because `x` has type `Box<i32>`, which does not implement the `Copy` trait
+   |                       --      ^ `x` is moved here
    |                       |
    |                       captured by this `Fn` closure
    |
@@ -17,9 +19,11 @@ error[E0507]: cannot move out of `x`, a captured variable in an `FnMut` closure
   --> $DIR/unboxed-closure-illegal-move.rs:19:35
    |
 LL |         let x = Box::new(0);
-   |             - captured outer variable
+   |             -   ----------- move occurs because `x` has type `Box<i32>`, which does not implement the `Copy` trait
+   |             |
+   |             captured outer variable
 LL |         let f = to_fn_mut(|| drop(x));
-   |                           --      ^ move occurs because `x` has type `Box<i32>`, which does not implement the `Copy` trait
+   |                           --      ^ `x` is moved here
    |                           |
    |                           captured by this `FnMut` closure
    |
@@ -32,9 +36,11 @@ error[E0507]: cannot move out of `x`, a captured variable in an `Fn` closure
   --> $DIR/unboxed-closure-illegal-move.rs:28:36
    |
 LL |         let x = Box::new(0);
-   |             - captured outer variable
+   |             -   ----------- move occurs because `x` has type `Box<i32>`, which does not implement the `Copy` trait
+   |             |
+   |             captured outer variable
 LL |         let f = to_fn(move || drop(x));
-   |                       -------      ^ move occurs because `x` has type `Box<i32>`, which does not implement the `Copy` trait
+   |                       -------      ^ `x` is moved here
    |                       |
    |                       captured by this `Fn` closure
 
@@ -42,9 +48,11 @@ error[E0507]: cannot move out of `x`, a captured variable in an `FnMut` closure
   --> $DIR/unboxed-closure-illegal-move.rs:32:40
    |
 LL |         let x = Box::new(0);
-   |             - captured outer variable
+   |             -   ----------- move occurs because `x` has type `Box<i32>`, which does not implement the `Copy` trait
+   |             |
+   |             captured outer variable
 LL |         let f = to_fn_mut(move || drop(x));
-   |                           -------      ^ move occurs because `x` has type `Box<i32>`, which does not implement the `Copy` trait
+   |                           -------      ^ `x` is moved here
    |                           |
    |                           captured by this `FnMut` closure